import math
import time
from datetime import datetime
import sys
import numpy.random
from ortools.sat.python import cp_model
import copy
import random
from itertools import combinations



max_value = sys.maxsize
min_value = -sys.maxsize

def load_without_splitting_car(goods_num,job_type,goods,detail_add_date):
    job_total = []
    job_type_total = []
    job_re = []
    car_d_num = []
    car_d_type = []
    car_d_goods_num = []
    goods_num_new = []
    order_sequence = []
    no_car_re = []
    no_job_data_re = []

    for i in range(len(goods_num)):

        sub_job_total = []
        sub_job_type_total = []
        sub_job_re = []
        sub_car_d_num = []
        sub_car_d_type = []
        sub_car_d_goods_num = []
        sub_goods_num_new = []




        for j in range(len(goods_num[i])):

            sub_sub_job_re = []
            sub_sub_job_total = []
            sub_sub_job_type_total = []
            sub_sub_car_d_num = []
            sub_sub_car_d_type = []
            sub_sub_car_d_goods_num = []
            sub_sub_goods_num_new = []
            sub_goods_num_new_jianxiang = 0
            sub_goods_num_new_zhanban = 0
            sub_job_total_jianxaing = 0
            sub_job_total_zhanban = 0
            if (len(detail_add_date[i][j])>0):
                order_sequence.append([i,j,detail_add_date[i][j][0]])

            for k in range(len(goods_num[i][j])):

                sub_sub_sub_job_re = []

                for a in range(len(goods_num[i][j][k])):

                    sub_sub_sub_job_re.append([i,j,k])
                    sub_sub_car_d_num.append(goods_num[i][j][k][a])
                    sub_sub_car_d_type.append(job_type[i][j][k][a])
                    sub_sub_car_d_goods_num.append(goods[i][j][k][a])
                    if (job_type[i][j][k][a]==1):
                        sub_job_total_jianxaing += goods_num[i][j][k][a]
                        sub_goods_num_new_jianxiang += goods[i][j][k][a]
                    else:
                        sub_job_total_zhanban += goods_num[i][j][k][a]
                        sub_goods_num_new_zhanban += goods[i][j][k][a]
                sub_sub_job_re.append(sub_sub_sub_job_re)


            if sub_job_total_jianxaing > 0:
                sub_sub_job_total.append(sub_job_total_jianxaing)
                sub_sub_job_type_total.append(1)
                sub_sub_goods_num_new.append(sub_goods_num_new_jianxiang)
            if sub_job_total_zhanban > 0:
                sub_sub_job_total.append(sub_job_total_zhanban)
                sub_sub_job_type_total.append(0)
                sub_sub_goods_num_new.append(sub_goods_num_new_zhanban)
            sub_job_total.append([sub_sub_job_total])
            sub_job_type_total.append([sub_sub_job_type_total])
            sub_job_re.append(sub_sub_job_re)
            sub_car_d_num.append([sub_sub_car_d_num])
            sub_car_d_type.append([sub_sub_car_d_type])
            sub_car_d_goods_num.append([sub_sub_car_d_goods_num])
            sub_goods_num_new.append([sub_sub_goods_num_new])

        job_total.append(sub_job_total)
        job_type_total.append(sub_job_type_total)
        job_re.append(sub_job_re)
        car_d_num.append(sub_car_d_num)
        car_d_type.append(sub_car_d_type)
        car_d_goods_num.append(sub_car_d_goods_num)
        goods_num_new.append(sub_goods_num_new)

    order_sequence.sort(key = lambda x:x[2])
    return job_total, job_type_total, job_re, goods_num_new, car_d_num, car_d_type, car_d_goods_num, no_car_re, no_job_data_re,order_sequence



def load_fun_3(job_data, job_type, n, f_p, max_c, tr, goods):
    '''
    EMS装车模型
    :param job_data: EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    :param job_type: EMS货物形态 0可代表栈板，1代表件箱，对应于EMS货物的形态，1是件箱，0是栈板，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，订单类型
    :param n: EMS的数量，用于区分EMS和自制
    :param f_p: 浮动参数，维度1，维度2 =  厂家，浮动系数
    :param max_c: 车的容量，转换为件箱的数量，维度1，维度2 =  厂家，最大容量
    :param tr: 栈板转换系数，维度1，维度2 =  厂家，转化系数
    :param goods: 栈板转换系数，维度1，维度2 =  厂家，转化系数
    :return: job_total:装车模型，记录每辆车装载的货物量
    car:每辆车装的货物量(乘了转化系数)，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    out_car：每辆车装的货物量(没乘转化系数)，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    car_type：装车模型的货物类型，与car相对应，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物类型
    job_re_r:记录每辆车装载的货物在job_data中的编号；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，编号；如[1,0,1,0]表示第一个厂家第零个订单第一个订单详情第零个货物
    job_re:记录每辆车装载的货物在job_data中的编号；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，编号；如[1,0,1]表示第一个厂家第零个订单第一个订单详情
    goods_num_new：每辆车装的总货物数量，相当于car_goods_d在第四个维度求和；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    job_total:每辆车装的货物量，相当于car在第四个维度求和；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    job_type_total:每辆车装的总货物类型，与car_type相关；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物类型
    car_goods_d:每辆车装的货物数量，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    '''
    car = []
    out_car = []
    job_re = []
    job_re_r = []
    car_type = []
    sub_car_type = []
    sub_job = []
    out_sub_job = []
    sub_re = []
    sub_re_r = []

    for i in range(len(job_data)):
        # 厂家层级遍历
        out_u_sub_car = []
        u_sub_car = []
        u_sub_job_re = []
        u_sub_job_re_r = []
        car_type_s = []

        for j in range(len(job_data[i])):
            # 订单层级遍历
            c = 0
            out_sub_car = []
            sub_car = []
            sub_job_re = []
            sub_job_re_r = []
            sub_sub_car_type = []
            k_num = 0
            d_num = sum(map(lambda x: len(x), job_data[i][j]))  # 得到订单的长度，为浮动处理做准备

            ch_list = []

            for k in range(len(job_data[i][j])):
                for a in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][a] != 0:  # 货物为件箱
                        ch_list.append(job_data[i][j][k][a])
                    else:  # 货物为栈板，转换成件箱，方便装车模型计算
                        ch_list.append(job_data[i][j][k][a] * tr[i])
            ch_list_i = len(ch_list) - 1
            while ch_list_i > 0:
                ch_list[ch_list_i - 1] += ch_list[ch_list_i]
                ch_list_i -= 1
            for k in range(len(job_data[i][j])):
                # 订单详情层级遍历
                for a in range(len(job_data[i][j][k])):
                    # 订单详情内部遍历，订单详情可能件箱，栈板同时存在
                    k_num += 1
                    if job_type[i][j][k][a] != 0:  # 货物为件箱
                        ch = job_data[i][j][k][a]
                    else:  # 货物为栈板，转换成件箱，方便装车模型计算
                        ch = job_data[i][j][k][a] * tr[i]  # tr[i]对应着厂家的转换系数
                    if c + ch_list[k_num - 1] <= max_c[i] * (1 + f_p[i]):
                        m_c = max_c[i] * (1 + f_p[i])
                    else:
                        m_c = max_c[i]  # 不同厂家可能会用到不同类型的货车，这里找到厂家对应的货车的容量，m_c就是货车对应的容量（转化为件箱的容量后）
                    while True:
                        if c + ch <= m_c:  # c为这个车累计的容量，一开始为0，ch为订单详情内件箱的数量，或栈板转换为件箱的数量，c + ch <= m_c说明这个车可能还没装满，满足约束
                            c += ch  # 满足容量约束，累计一下货物数量
                            if job_type[i][j][k][a] == 1:  # 记录车要装载的货物数量和类型
                                out_sub_car.append(ch)
                                sub_sub_car_type.append(1)
                            else:
                                out_sub_car.append(ch // tr[i])  # 将转换后的栈板数量转化回去
                                sub_sub_car_type.append(0)
                            sub_car.append(ch)
                            sub_job_re.append([i, j, k])  # 记录订单详情的下标
                            sub_job_re_r.append([i, j, k, a])  # 记录订单详情的下标

                            if c == m_c:  # 车装满了，初始化一些变量，用来重新记录下一辆车
                                sub_job.append(sub_car)
                                out_sub_job.append(out_sub_car)
                                sub_car_type.append(sub_sub_car_type)
                                sub_re.append(sub_job_re)
                                sub_re_r.append(sub_job_re_r)
                                sub_car = []
                                out_sub_car = []
                                sub_sub_car_type = []
                                sub_job_re = []
                                sub_job_re_r = []
                                c = 0
                                break

                            if k_num == d_num:  # 到了最后一个订单详情了，需要进行订单隔离了，初始化一些变量，用来重新记录下一辆车
                                sub_job.append(sub_car)
                                out_sub_job.append(out_sub_car)
                                sub_car_type.append(sub_sub_car_type)
                                sub_re.append(sub_job_re)
                                sub_re_r.append(sub_job_re_r)
                                sub_car = []
                                out_sub_car = []
                                sub_sub_car_type = []
                                sub_job_re = []
                                sub_job_re_r = []
                                c = 0

                            break
                        elif c < m_c and c + ch > m_c:  # 当前车的容量装不下当前订单详情的货物量，需要分车来装或者浮动一下

                            if job_type[i][j][k][a] == 0:  # 货物形态为栈板
                                rr = (m_c - c) // tr[i]  # 判断剩余的容量是否能装整数个栈板
                                if rr != 0:  # 能装下一个以上的栈板
                                    out_sub_car.append(rr)
                                    sub_sub_car_type.append(0)
                                    sub_car.append(rr * tr[i])
                                    sub_job_re.append([i, j, k])
                                    sub_job_re_r.append([i, j, k, a])
                                    sub_job.append(sub_car)
                                    out_sub_job.append(out_sub_car)
                                    sub_car_type.append(sub_sub_car_type)
                                    sub_re.append(sub_job_re)
                                    sub_re_r.append(sub_job_re_r)
                                    sub_car = []
                                    out_sub_car = []
                                    sub_sub_car_type = []
                                    sub_job_re = []
                                    sub_job_re_r = []
                                    ch = ch - rr * tr[i]
                                    c = 0
                                else:  # 一个栈板都装不下
                                    c = 0
                                    out_sub_job.append(out_sub_car)
                                    sub_car_type.append(sub_sub_car_type)
                                    sub_job.append(sub_car)
                                    sub_re.append(sub_job_re)
                                    sub_re_r.append(sub_job_re_r)
                                    sub_car = []
                                    out_sub_car = []
                                    sub_sub_car_type = []
                                    sub_job_re = []
                                    sub_job_re_r = []

                            else:  # 件箱分车装
                                out_sub_car.append(m_c - c)
                                sub_sub_car_type.append(1)
                                sub_car.append(m_c - c)
                                sub_job_re.append([i, j, k])
                                sub_job_re_r.append([i, j, k, a])
                                sub_job.append(sub_car)
                                out_sub_job.append(out_sub_car)
                                sub_car_type.append(sub_sub_car_type)
                                sub_re.append(sub_job_re)
                                sub_re_r.append(sub_job_re_r)
                                sub_car = []
                                out_sub_car = []
                                sub_sub_car_type = []
                                sub_job_re = []
                                sub_job_re_r = []
                                ch = ch - (m_c - c)
                                c = 0

            u_sub_car.append(sub_job)
            out_u_sub_car.append(out_sub_job)
            car_type_s.append(sub_car_type)
            u_sub_job_re.append(sub_re)
            u_sub_job_re_r.append(sub_re_r)
            sub_car_type = []
            sub_job = []
            out_sub_job = []
            sub_re = []
            sub_re_r = []

        car.append(u_sub_car)
        car_type.append(car_type_s)
        out_car.append(out_u_sub_car)
        job_re.append(u_sub_job_re)
        job_re_r.append(u_sub_job_re_r)
    # -----------------------------------------------------------------------------------------------------------------------
    # 该段代码用于把与货物内部数量相关的列表数据合并，方便后续的遍历处理，所谓货物内部数量，就是指一个箱子，一个栈板内部的装的货物数量
    # [[[[100000.0], [500.0]]]] -> [[[100000.0, 500.0]]]
    store = []
    end_goods = []
    for i in range(len(goods)):
        sub_goods = []
        for j in range(len(goods[i])):
            for k in range(len(goods[i][j])):
                store += goods[i][j][k]
        sub_goods.append(store)
        store = []
        end_goods.append(sub_goods)
    # -----------------------------------------------------------------------------------------------------------------------
    # 该段代码用于处理时间窗求解函数的输入，即对装车模型得到的装车数据进行处理
    goods_num_new = []
    job_total = []
    job_type_total = []
    car_goods_d = []
    for i in range(len(job_re)):  # 厂家层级遍历
        job_sub = []
        type_sub = []
        ss_goods_num = []
        sub_car_goods_d = []
        num = 0
        for j in range(len(job_re[i])):  # 订单层级遍历
            sub_ss_goods_num = []
            u_job_sub = []
            u_type_sub = []
            sub_sub_car_goods_d = []
            for q in range(len(job_re[i][j])):  # 车辆层级遍历
                e = 0
                m = 0
                g_0 = 0
                g_1 = 0
                sub_sub_ss_goods_num = []
                p_type = []
                type_sub_sub = []
                job_sub_sub = []
                sub_sub_sub_car_goods_d = []
                for k in range(len(job_re[i][j][q])):  # 订单详情层级遍历
                    b_num = num
                    if job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
                        job_re_r[i][j][q][k][3]] == 0:
                        num += int(car[i][j][q][k] / tr[i])  # 用作取货物内部数量的下标
                        m += int(car[i][j][q][k] / tr[i])  # 将一个车里的同一类货物累加起来
                        sub_sub_sub_car_goods_d.append(sum(end_goods[i][0][b_num:num]))  # 得到订单详情的货物内部数量，方便后续计算
                        g_0 += sum(end_goods[i][0][b_num:num])  # 累积同一辆车同一类型货物内部数量
                        p_type.append(0)  # 记录货物类型，方便判断
                    elif job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
                        job_re_r[i][j][q][k][3]] == 1:
                        num += car[i][j][q][k]  # 用作取货物内部数量的下标
                        e += car[i][j][q][k]  # 将一个车里的同一类货物累加起来
                        sub_sub_sub_car_goods_d.append(sum(end_goods[i][0][b_num:num]))  # 得到订单详情的货物内部数量，方便后续计算
                        g_1 += sum(end_goods[i][0][b_num:num])  # 累积同一辆车同一类型货物内部数量
                        p_type.append(1)  # 记录货物类型，方便判断

                if 1 in p_type:
                    type_sub_sub.append(1)
                    job_sub_sub.append(e)
                    sub_sub_ss_goods_num.append(g_1)

                if 0 in p_type:
                    type_sub_sub.append(0)
                    job_sub_sub.append(m)
                    sub_sub_ss_goods_num.append(g_0)

                sub_sub_car_goods_d.append(sub_sub_sub_car_goods_d)
                u_job_sub.append(job_sub_sub)
                u_type_sub.append(type_sub_sub)
                sub_ss_goods_num.append(sub_sub_ss_goods_num)
            sub_car_goods_d.append(sub_sub_car_goods_d)
            job_sub.append(u_job_sub)
            type_sub.append(u_type_sub)
            ss_goods_num.append(sub_ss_goods_num)
        car_goods_d.append(sub_car_goods_d)
        job_total.append(job_sub)
        job_type_total.append(type_sub)
        goods_num_new.append(ss_goods_num)
    # # job_total: [[[[2], [1]]], [[[1]]], [[[2]]], [[[1]]], [[[3], [1, 1]]]]
    # [[[[3]]], [[[1]]], [[[2]]], [[[1]]], [[[3], [1, 1]]]]
    job_re = copy.deepcopy(job_re)
    return job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d


# def load_se(job_data, job_type, max_c, tr, goods, car_num):
#     '''
#     自制装车模型
#     :param job_data: 自制任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量
#     :param job_data: 自制任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量
#     :param job_type: 自制货物形态 0可代表栈板，1代表件箱
#     :param max_c: 车的容量，转换为件箱的数量
#     :param tr: 栈板转换系数
#     :param goods: 货物内部数量
#     :param car_num:自制发车表车的数量
#     :return:job_total：装车模型，记录每辆车装载的货物量
#     job_type_total：对应装车的货物类型
#     job_re：记录每辆车装载的货物编号
#     goods_num_new：对应装车货物内部类型
#     out_car：为了得到客户想要的输出，后续为d_process函数使用，跟装车模型相关
#     car_type：为了得到客户想要的输出，后续为d_process函数使用，跟装车模型的货物类型相关
#     car_goods_d：为了得到客户想要的输出，后续为d_process函数使用，跟装车模型的货物内部数量相关
#     '''
#     car = []
#     out_car = []
#     job_re = []
#     job_re_r = []
#     car_type = []
#     sub_car_type = []
#     sub_job = []
#     out_sub_job = []
#     sub_re = []
#     sub_re_r = []
#
#     for i in range(len(job_data)):
#         # 厂家层级遍历
#         out_u_sub_car = []
#         u_sub_car = []
#         u_sub_job_re = []
#         u_sub_job_re_r = []
#         car_type_s = []
#
#         for j in range(len(job_data[i])):
#             # 订单层级遍历
#             c = 0
#             out_sub_car = []
#             sub_car = []
#             sub_job_re = []
#             sub_job_re_r = []
#             sub_sub_car_type = []
#             k_num = 0
#             d_num = sum(map(lambda x: len(x), job_data[i][j]))  # 得到订单的长度，为浮动处理做准备
#
#             for k in range(len(job_data[i][j])):
#                 # 订单详情层级遍历
#                 for a in range(len(job_data[i][j][k])):
#                     # 订单详情内部遍历，订单详情可能件箱，栈板同时存在
#                     k_num += 1
#                     if job_type[i][j][k][a] != 0:  # 货物为件箱
#                         ch = job_data[i][j][k][a]
#                     else:  # 货物为栈板，转换成件箱，方便装车模型计算
#                         ch = job_data[i][j][k][a] * tr[i]  # tr[i]对应着厂家的转换系数
#                     m_c = max_c[i]  # 不同厂家可能会用到不同类型的货车，这里找到厂家对应的货车的容量，m_c就是货车对应的容量（转化为件箱的容量后）
#                     while True:
#                         if c + ch <= m_c:  # c为这个车累计的容量，一开始为0，ch为订单详情内件箱的数量，或栈板转换为件箱的数量，c + ch <= m_c说明这个车可能还没装满，满足约束
#                             c += ch  # 满足容量约束，累计一下货物数量
#
#                             if job_type[i][j][k][a] == 1:  # 记录车要装载的货物数量和类型
#                                 out_sub_car.append(ch)
#                                 sub_sub_car_type.append(1)
#                             else:
#                                 out_sub_car.append(ch // tr[i])  # 将转换后的栈板数量转化回去
#                                 sub_sub_car_type.append(0)
#                             sub_car.append(ch)
#                             sub_job_re.append([i, j, k])  # 记录订单详情的下标
#                             sub_job_re_r.append([i, j, k, a])  # 记录订单详情的下标
#
#                             if c == m_c:  # 车装满了，初始化一些变量，用来重新记录下一辆车
#                                 sub_job.append(sub_car)
#                                 out_sub_job.append(out_sub_car)
#                                 sub_car_type.append(sub_sub_car_type)
#                                 sub_re.append(sub_job_re)
#                                 sub_re_r.append(sub_job_re_r)
#                                 sub_car = []
#                                 out_sub_car = []
#                                 sub_sub_car_type = []
#                                 sub_job_re = []
#                                 sub_job_re_r = []
#                                 c = 0
#                                 break
#
#                             if k_num == d_num:  # 到了最后一个订单详情了，需要进行订单隔离了，初始化一些变量，用来重新记录下一辆车
#                                 sub_job.append(sub_car)
#                                 out_sub_job.append(out_sub_car)
#                                 sub_car_type.append(sub_sub_car_type)
#                                 sub_re.append(sub_job_re)
#                                 sub_re_r.append(sub_job_re_r)
#                                 sub_car = []
#                                 out_sub_car = []
#                                 sub_sub_car_type = []
#                                 sub_job_re = []
#                                 sub_job_re_r = []
#                                 c = 0
#
#                             break
#                         elif c < m_c and c + ch > m_c:  # 当前车的容量装不下当前订单详情的货物量，需要分车来装或者浮动一下
#                             if k_num == d_num:  # 自制无浮动处理
#                                 if c + ch <= m_c:
#                                     if job_type[i][j][k][a] == 1:  # 记录货物的数量和类型
#                                         out_sub_car.append(ch)
#                                         sub_sub_car_type.append(1)
#                                     else:
#                                         out_sub_car.append(ch // tr[i])
#                                         sub_sub_car_type.append(0)
#                                     sub_car.append(ch)
#                                     sub_job_re.append([i, j, k])  # 记录订单详情的下标
#                                     sub_job_re_r.append([i, j, k, a])  # 记录订单详情的下标
#                                     sub_job.append(sub_car)
#                                     out_sub_job.append(out_sub_car)
#                                     sub_car_type.append(sub_sub_car_type)
#                                     sub_re.append(sub_job_re)
#                                     sub_re_r.append(sub_job_re_r)
#                                     break
#                                 else:  # 得分车装
#                                     if job_type[i][j][k][a] != 0:
#                                         out_sub_car.append(m_c - c)
#                                         sub_sub_car_type.append(1)
#                                         sub_car.append(m_c - c)
#                                         sub_job_re.append([i, j, k])
#                                         sub_job_re_r.append([i, j, k, a])
#                                         sub_job.append(sub_car)
#                                         out_sub_job.append(out_sub_car)
#                                         sub_car_type.append(sub_sub_car_type)
#                                         sub_re.append(sub_job_re)
#                                         sub_re_r.append(sub_job_re_r)
#                                         sub_car = []
#                                         out_sub_car = []
#                                         sub_sub_car_type = []
#                                         sub_job_re = []
#                                         sub_job_re_r = []
#                                         ch = ch - (m_c - c)
#                                         c = 0
#                                     else:  # 栈板分车装，一个栈板虽然可以转化为多个件箱，但是一个栈板只能装在一辆车里，不能拆开
#                                         rr = (m_c - c) // tr[i]  # 判断剩余的容量是否能装整数个栈板
#                                         if rr != 0:  # 能装下一个以上的栈板
#                                             out_sub_car.append(rr)
#                                             sub_sub_car_type.append(0)
#                                             sub_car.append(rr * tr[i])
#                                             sub_job_re.append([i, j, k])
#                                             sub_job_re_r.append([i, j, k, a])
#                                             sub_job.append(sub_car)
#                                             out_sub_job.append(out_sub_car)
#                                             sub_car_type.append(sub_sub_car_type)
#                                             sub_re.append(sub_job_re)
#                                             sub_re_r.append(sub_job_re_r)
#                                             sub_car = []
#                                             out_sub_car = []
#                                             sub_sub_car_type = []
#                                             sub_job_re = []
#                                             sub_job_re_r = []
#                                             ch = ch - rr * tr[i]
#                                             c = 0
#                                         else:  # 一个栈板都装不下
#                                             c = 0
#                                             out_sub_job.append(out_sub_car)
#                                             sub_car_type.append(sub_sub_car_type)
#                                             sub_job.append(sub_car)
#                                             sub_re.append(sub_job_re)
#                                             sub_re_r.append(sub_job_re_r)
#                                             sub_car = []
#                                             out_sub_car = []
#                                             sub_sub_car_type = []
#                                             sub_job_re = []
#                                             sub_job_re_r = []
#
#                             else:  # 当前的订单详情不是最后一个
#                                 if job_type[i][j][k][a] == 0:  # 货物形态为栈板
#                                     rr = (m_c - c) // tr[i]  # 判断剩余的容量是否能装整数个栈板
#                                     if rr != 0:  # 能装下一个以上的栈板
#                                         out_sub_car.append(rr)
#                                         sub_sub_car_type.append(0)
#                                         sub_car.append(rr * tr[i])
#                                         sub_job_re.append([i, j, k])
#                                         sub_job_re_r.append([i, j, k, a])
#                                         sub_job.append(sub_car)
#                                         out_sub_job.append(out_sub_car)
#                                         sub_car_type.append(sub_sub_car_type)
#                                         sub_re.append(sub_job_re)
#                                         sub_re_r.append(sub_job_re_r)
#                                         sub_car = []
#                                         out_sub_car = []
#                                         sub_sub_car_type = []
#                                         sub_job_re = []
#                                         sub_job_re_r = []
#                                         ch = ch - rr * tr[i]
#                                         c = 0
#                                     else:  # 一个栈板都装不下
#                                         c = 0
#                                         out_sub_job.append(out_sub_car)
#                                         sub_car_type.append(sub_sub_car_type)
#                                         sub_job.append(sub_car)
#                                         sub_re.append(sub_job_re)
#                                         sub_re_r.append(sub_job_re_r)
#                                         sub_car = []
#                                         out_sub_car = []
#                                         sub_sub_car_type = []
#                                         sub_job_re = []
#                                         sub_job_re_r = []
#
#                                 else:  # 件箱分车装
#                                     out_sub_car.append(m_c - c)
#                                     sub_sub_car_type.append(1)
#                                     sub_car.append(m_c - c)
#                                     sub_job_re.append([i, j, k])
#                                     sub_job_re_r.append([i, j, k, a])
#                                     sub_job.append(sub_car)
#                                     out_sub_job.append(out_sub_car)
#                                     sub_car_type.append(sub_sub_car_type)
#                                     sub_re.append(sub_job_re)
#                                     sub_re_r.append(sub_job_re_r)
#                                     sub_car = []
#                                     out_sub_car = []
#                                     sub_sub_car_type = []
#                                     sub_job_re = []
#                                     sub_job_re_r = []
#                                     ch = ch - (m_c - c)
#                                     c = 0
#
#             u_sub_car.append(sub_job)
#             out_u_sub_car.append(out_sub_job)
#             car_type_s.append(sub_car_type)
#             u_sub_job_re.append(sub_re)
#             u_sub_job_re_r.append(sub_re_r)
#             sub_car_type = []
#             sub_job = []
#             out_sub_job = []
#             sub_re = []
#             sub_re_r = []
#
#         car.append(u_sub_car)
#         car_type.append(car_type_s)
#         out_car.append(out_u_sub_car)
#         job_re.append(u_sub_job_re)
#         job_re_r.append(u_sub_job_re_r)
#
#     # -----------------------------------------------------------------------------------------------------------------------
#     # 该段代码用于把与货物内部数量相关的列表数据合并，方便后续的遍历处理，所谓货物内部数量，就是指一个箱子，一个栈板内部的装的货物数量
#     # [[[[100000.0], [500.0]]]] -> [[[100000.0, 500.0]]]
#
#     store = []
#     end_goods = []
#     for i in range(len(goods)):
#         sub_goods = []
#         for j in range(len(goods[i])):
#             for k in range(len(goods[i][j])):
#                 store += goods[i][j][k]
#         sub_goods.append(store)
#         store = []
#         end_goods.append(sub_goods)
#
#     # -----------------------------------------------------------------------------------------------------------------------
#     # 该段代码用于处理时间窗求解函数的输入，即对装车模型得到的装车数据进行处理
#
#     goods_num_new = []
#     job_total = []
#     job_type_total = []
#     car_goods_d = []
#     for i in range(len(job_re)):  # 厂家层级遍历
#         job_sub = []
#         type_sub = []
#         ss_goods_num = []
#         sub_car_goods_d = []
#         num = 0
#         for j in range(len(job_re[i])):  # 订单层级遍历
#             sub_ss_goods_num = []
#             u_job_sub = []
#             u_type_sub = []
#             sub_sub_car_goods_d = []
#             for q in range(len(job_re[i][j])):  # 车辆层级遍历
#                 e = 0
#                 m = 0
#                 g_0 = 0
#                 g_1 = 0
#                 sub_sub_ss_goods_num = []
#                 p_type = []
#                 type_sub_sub = []
#                 job_sub_sub = []
#                 sub_sub_sub_car_goods_d = []
#                 for k in range(len(job_re[i][j][q])):  # 订单详情层级遍历
#                     b_num = num
#                     if job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
#                         job_re_r[i][j][q][k][3]] == 0:
#                         num += int(car[i][j][q][k] / tr[i])  # 用作取货物内部数量的下标
#                         m += int(car[i][j][q][k] / tr[i])  # 将一个车里的同一类货物累加起来
#                         sub_sub_sub_car_goods_d.append(sum(end_goods[i][0][b_num:num]))  # 得到订单详情的货物内部数量，方便后续计算
#                         g_0 += sum(end_goods[i][0][b_num:num])  # 累积同一辆车同一类型货物内部数量
#                         p_type.append(0)  # 记录货物类型，方便判断
#                     elif job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
#                         job_re_r[i][j][q][k][3]] == 1:
#                         num += car[i][j][q][k]  # 用作取货物内部数量的下标
#                         e += car[i][j][q][k]  # 将一个车里的同一类货物累加起来
#                         sub_sub_sub_car_goods_d.append(sum(end_goods[i][0][b_num:num]))  # 得到订单详情的货物内部数量，方便后续计算
#                         g_1 += sum(end_goods[i][0][b_num:num])  # 累积同一辆车同一类型货物内部数量
#                         p_type.append(1)  # 记录货物类型，方便判断
#
#                 if 1 in p_type:
#                     type_sub_sub.append(1)
#                     job_sub_sub.append(e)
#                     sub_sub_ss_goods_num.append(g_1)
#
#                 if 0 in p_type:
#                     type_sub_sub.append(0)
#                     job_sub_sub.append(m)
#                     sub_sub_ss_goods_num.append(g_0)
#
#                 sub_sub_car_goods_d.append(sub_sub_sub_car_goods_d)
#                 u_job_sub.append(job_sub_sub)
#                 u_type_sub.append(type_sub_sub)
#                 sub_ss_goods_num.append(sub_sub_ss_goods_num)
#             sub_car_goods_d.append(sub_sub_car_goods_d)
#             job_sub.append(u_job_sub)
#             type_sub.append(u_type_sub)
#             ss_goods_num.append(sub_ss_goods_num)
#         car_goods_d.append(sub_car_goods_d)
#         job_total.append(job_sub)
#         job_type_total.append(type_sub)
#         goods_num_new.append(ss_goods_num)
#
#     car_num_check = 0
#
#     # for i in range(len(job_total)):
#     #     for j in range(len(job_total[i])):
#     #         car_num_check += len(job_total[i][j])
#
#     total_car_num = 0
#
#     no_car_re_temp = []
#     no_car_type_temp = []
#     no_out_car_temp = []
#     # for i in range(len(car_num)):
#     #     total_car_num += sum(car_num[i])
#     # # 缺车的话，会返回缺车的订单详情的下标
#     # if car_num_check > total_car_num:
#     #     job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, no_re = zz_process(job_total,
#     #                                                                                                          job_type_total,
#     #                                                                                                          job_re,
#     #                                                                                                          goods_num_new,
#     #                                                                                                          out_car,
#     #                                                                                                          car_type,
#     #                                                                                                          car_goods_d,
#     #                                                                                                          car_num)
#     for i in range(len(job_total)):
#         total_car_num = sum(car_num[i])
#         car_num_check = 0
#         for j in range(len(job_total[i])):
#             for k in range(len(job_total[i][j])):
#                 if car_num_check < total_car_num:
#                     car_num_check += 1
#                 else:
#                     no_car_re_temp += job_re[i][j][k:len(job_re[i][j])]
#                     no_out_car_temp += out_car[i][j][k:len(out_car[i][j])]
#                     no_car_type_temp += car_type[i][j][k:len(car_type[i][j])]
#                     del job_total[i][j][k:len(job_total[i][j])]
#                     del job_type_total[i][j][k:len(job_type_total[i][j])]
#                     del job_re[i][j][k:len(job_re[i][j])]
#                     del goods_num_new[i][j][k:len(goods_num_new[i][j])]
#                     del out_car[i][j][k:len(out_car[i][j])]
#                     del car_type[i][j][k:len(car_type[i][j])]
#                     del car_goods_d[i][j][k:len(car_goods_d[i][j])]
#                     break
#
#     no_car_re_temp = sum(no_car_re_temp, [])
#     no_car_type_temp = sum(no_car_type_temp, [])
#     no_out_car_temp = sum(no_out_car_temp, [])
#
#     no_job_data_re_temp = [[no_car_type_temp[i] * no_out_car_temp[i], (1 - no_car_type_temp[i]) * no_out_car_temp[i]]
#                            for i in range(len(no_car_re_temp))]
#     no_car_re = []
#     no_job_data_re = []
#
#     if no_car_re_temp != []:
#         slow = 0
#         temp = no_job_data_re_temp[0]
#         for i in range(1, len(no_car_re_temp)):
#             if no_car_re_temp[i] != no_car_re_temp[slow]:
#                 no_job_data_re.append(temp)
#                 no_car_re.append(no_car_re_temp[slow])
#                 temp = [0, 0]
#                 slow = i
#
#             temp[0] += no_job_data_re_temp[i][0]
#             temp[1] += no_job_data_re_temp[i][1]
#         no_job_data_re.append(temp)
#         no_car_re.append(no_car_re_temp[slow])
#
#     return job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, no_car_re, no_job_data_re
def load_se(job_data, job_type, max_c, tr, goods, car_num,t,logger):
    '''
    自制装车模型
    :param job_data: EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    :param job_type: EMS货物形态 0可代表栈板，1代表件箱，对应于EMS货物的形态，1是件箱，0是栈板，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，订单类型
    :param n: EMS的数量，用于区分EMS和自制
    :param f_p: 浮动参数，维度1，维度2 =  厂家，浮动系数
    :param max_c: 车的容量，转换为件箱的数量，维度1，维度2 =  厂家，最大容量
    :param tr: 栈板转换系数，维度1，维度2 =  厂家，转化系数
    :param goods: 栈板转换系数，维度1，维度2 =  厂家，转化系数
    :param car_num: 每个厂家的车辆数量，维度1，维度2 =  厂家，车辆数量
    :return:
    job_list:决策变量，表示某个订单详情放入该厂家的某辆车中的货物数量，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，该厂家的某辆车的货物数量
    job_total:装车模型，记录每辆车装载的货物量
    car:每辆车装的货物量(乘了转化系数)，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    out_car：每辆车装的货物量(没乘转化系数)，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    car_type：装车模型的货物类型，与car相对应，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物类型
    job_re_r:记录每辆车装载的货物在job_data中的编号；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，编号；如[1,0,1,0]表示第一个厂家第零个订单第一个订单详情第零个货物
    job_re:记录每辆车装载的货物在job_data中的编号；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，编号；如[1,0,1]表示第一个厂家第零个订单第一个订单详情
    goods_num_new：每辆车装的总货物数量，相当于car_goods_d在第四个维度求和；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    job_total:每辆车装的货物量，相当于car在第四个维度求和；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    job_type_total:每辆车装的总货物类型，与car_type相关；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物类型
    car_goods_d:每辆车装的货物数量，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    no_car_re:返回未排的订单详情标号
    no_job_data_re，返回未排的货物数量，前件箱后栈板
    '''
    no_car_re = []
    no_job_data_re = []
    model = cp_model.CpModel()
    job_data_flatten = [[] for _ in range(len(job_data))]    #展平job_data，方便后续计算
    job_type_flatten = [[] for _ in range(len(job_type))]  #展平job_type，方便后续计算
    job_re_flatten = [[] for _ in range(len(job_data))]  #展平job_re，方便后续计算
    job_re_r_flatten = [[] for _ in range(len(job_data))] #展平job_re_r，方便后续计算
    car_num_flatten = [ [] for _ in range(len(car_num))] #展平car_num，方便后续计算



    for i in range(len(job_data)):#对数据展平，因为装车和具体的订单详情无关，所以将订单详情那一位维合并
        for j in range(len(job_data[i])):
            sub_job_data_flatten = []
            sub_job_type_flatten = []
            sub_job_re_flatten = []
            sub_job_re_r_flatten = []
            for k in range(len(job_data[i][j])):
                for a in range(len(job_data[i][j][k])):
                    sub_job_data_flatten.append(job_data[i][j][k][a])
                    sub_job_type_flatten.append(job_type[i][j][k][a])
                    sub_job_re_flatten.append([i,j,k])
                    sub_job_re_r_flatten.append([i,j,k,a])
            job_data_flatten[i].append(sub_job_data_flatten)
            job_type_flatten[i].append(sub_job_type_flatten)
            job_re_flatten[i].append(sub_job_re_flatten)
            job_re_r_flatten[i].append(sub_job_re_r_flatten)


    for i in range(len(car_num)): #对车辆数量展平
        car_num_flatten[i]  = sum(car_num[i])


    job_list = []

    for i in range(len(job_data_flatten)):#建立决策变量
        sub_job_list = []
        for j in range(len(job_data_flatten[i])):
            sub_sub_job_list = []
            for k in range(len(job_data_flatten[i][j])):
                sub_sub_sub_job_list = []
                for a in range(car_num_flatten[i]):
                    sub_sub_sub_job_list.append(model.NewIntVar(0, job_data_flatten[i][j][k],
                                'p_s_%d_%d_%d_%d' % (i, j, k,a)))
                sub_sub_job_list.append(sub_sub_sub_job_list)
            sub_job_list.append(sub_sub_job_list)
        job_list.append(sub_job_list)

    for i in range(len(job_list)): #每个货物分配到该厂家的所有车辆的货物数量总和小于等于该货物的数量总和
        for j in range(len(job_list[i])):
            for k in range(len(job_list[i][j])):
                model.Add(sum(job_list[i][j][k])<=job_data_flatten[i][j][k])



    for i in range(len(job_list)):#每辆车所装的货物数量总和不能超过该车的最大容量
        for j in range(len(job_list[i][0][0])):  # 遍历z维
            sub_job_list = []  # 当前列的列表
            for k in range(len(job_list[i])):  # 遍历第一维（x）的每个子列表
                for a in range(len(job_list[i][k])):  # 遍历第二维（y）的每个子子列表
                    sub_job_list.append(job_list[i][k][a][j]*(job_type_flatten[i][k][a] + (1-job_type_flatten[i][k][a])*tr[i]))
            model.Add(sum(sub_job_list) <= max_c[i])

    c_load = []
    for i in range(len(job_list)):#每辆车的容量为分配到该车的货物数量总和
        sub_c_load = []
        for j in range(len(job_list[i][0][0])):
            sub_sub_c_load = []
            for k in range(len(job_list[i])):
                for a in range(len(job_list[i][k])):
                    sub_sub_c_load.append(job_list[i][k][a][j]*(job_type_flatten[i][k][a] + (1-job_type_flatten[i][k][a])*tr[i]))  # 将当前位置的元素添加到当前列
            c = model.NewIntVar(0, 99999999, 'c_load_%d_%d' % (i, j))
            model.Add(sum(sub_sub_c_load) ==c)
            sub_c_load.append(c)
        c_load.append(sub_c_load)

    for i in range(len(c_load)):#排在前面的车所装的货物数量需要大于后面的
        for j in range(len(c_load[i])-1):
            for k in range(j+1,len(c_load[i])):
                model.Add(c_load[i][j]>=c_load[i][k])


    in_stock = []#第二次求解最小化车辆数量，并将该目标值作为第三次求解的约束
    for i in range(len(job_list)):
        for j in range(len(job_list[i][0][0])):
            sub_have_job = []
            for k in range(len(job_list[i])):
                for a in range(len(job_list[i][k])):
                    sub_have_job.append(job_list[i][k][a][j])
            i_s = model.NewBoolVar('p_s_%d_%d' % (i,j))
            model.Add(sum(sub_have_job) >0).OnlyEnforceIf(i_s)
            model.Add(sum(sub_have_job) ==0).OnlyEnforceIf(i_s.Not())
            in_stock.append(i_s)

    have_only_one = []#第三次求解最小化同时装了件箱和栈板的车辆的数量，增加自制求解算法得到解的概率
    for i in range(len(job_list)):
        for j in range(len(job_list[i][0][0])):
            have_only_piece_box = []
            have_only_pallet = []
            for k in range(len(job_list[i])):
                for a in range(len(job_list[i][k])):
                    if(job_type_flatten[i][k][a])==1:
                        have_only_piece_box.append(job_list[i][k][a][j])
                    else:
                        have_only_pallet.append(job_list[i][k][a][j])
            if len(have_only_piece_box)>0 and len(have_only_pallet)>0:

                pi = model.NewBoolVar('p_i_%d_%d' % (i,j))
                model.Add(sum(have_only_piece_box) >0).OnlyEnforceIf(pi)  #表示只有件箱
                model.Add(sum(have_only_piece_box) ==0).OnlyEnforceIf(pi.Not())

                pa = model.NewBoolVar('p_a_%d_%d' % (i,j))
                model.Add(sum(have_only_pallet) >0).OnlyEnforceIf(pa) #表示只有栈板
                model.Add(sum(have_only_pallet) ==0).OnlyEnforceIf(pa.Not())

                pipa = model.NewBoolVar('pipa_%d_%d' % (i,j))  #表示一辆车不同时出现件箱和栈板
                model.AddMultiplicationEquality(pipa, [pa, pi])
                have_only_one.append(pipa)


    for i in range(len(job_list)):#订单隔离
        if len(job_list[i]) >1:
            combins = [c for c in combinations(range(len(job_list[i])), 2)]
            for c in combins:
                for j in range(len(job_list[i][c[0]])):
                    for k in range(len(job_list[i][c[1]])):
                        for a in range(car_num_flatten[i]):
                            model.AddMultiplicationEquality(0, [job_list[i][c[0]][j][a],job_list[i][c[1]][k][a]])

    obj = []#第一个目标值，排的货物总量最多
    for i in range(len(job_list)):
        for j in range(len(job_list[i])):
            for k in range(len(job_list[i][j])):
                for a in range(len(job_list[i][j][k])):
                    obj.append(job_list[i][j][k][a])

    #第一次求解要求拍的货最多
    model.Maximize(sum(obj))
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8
    solver.parameters.max_time_in_seconds = t
    status = solver.Solve(model)
    #第二次求解要求排的车最少
    model.Add(sum(obj) == round(solver.ObjectiveValue()))
    model.Minimize(sum(in_stock))
    status2 = solver.Solve(model)
    #第三次求解要求件箱和栈板分开来
    model.Add(sum(in_stock) == round(solver.ObjectiveValue()))
    model.Minimize(sum(have_only_one))
    status3 = solver.Solve(model)
    # 得到最终的解

    if status == cp_model.OPTIMAL and status2 == cp_model.OPTIMAL and status3==cp_model.OPTIMAL:
        logger.info("自制装车模型求得最优解")
    elif (status == cp_model.FEASIBLE or status == cp_model.OPTIMAL) and (status2 == cp_model.FEASIBLE or status2 == cp_model.OPTIMAL) and (status3 == cp_model.FEASIBLE or status3 == cp_model.OPTIMAL):
        logger.info("自制装车模型求得次优解")
    else :
        logger.error("自制装车模型无解，程序结束")
        exit()

    solution = []
    for i in range(len(job_list)):
        sub_job_list = []
        for j in range(len(job_list[i])):
            sub_sub_job_list = []
            for k in range(len(job_list[i][j])):
                sub_sub_sub_job_list = []
                for a in range(len(job_list[i][j][k])):
                    sub_sub_sub_job_list.append(solver.Value(job_list[i][j][k][a]))
                sb = sum(sub_sub_sub_job_list)
                if sb < job_data_flatten[i][j][k]:
                    no_car_re.append(copy.deepcopy(job_re_flatten[i][j][k]))
                    no_job_data_re.append(copy.deepcopy([job_type_flatten[i][j][k] * (job_data_flatten[i][j][k]- sb), (1 - job_type_flatten[i][j][k]) *( job_data_flatten[i][j][k]- sb)]))
                sub_sub_job_list.append(sb)
            sub_job_list.append(sub_sub_job_list)
        solution.append(sub_job_list)

    car = []
    car_type = []
    out_car = []
    job_re = []
    job_re_r = []
    for i in range(len(job_list)):
        sub_car = []
        sub_car_type = []
        sub_out_car = []
        sub_job_re = []
        sub_job_re_r = []
        for j in range(len(job_list[i])):
            sub_sub_car = []
            sub_sub_car_type = []
            sub_sub_out_car = []
            sub_sub_job_re = []
            sub_sub_job_re_r = []
            for k in range(len(job_list[i][j][0])):
                sub_sub_sub_car = []
                sub_sub_sub_car_type = []
                sub_sub_sub_out_car = []
                sub_sub_sub_job_re = []
                sub_sub_sub_job_re_r = []
                for a in range(len(job_list[i][j])):
                    if solver.Value(job_list[i][j][a][k]) >0:
                        sub_sub_sub_car.append(solver.Value(job_list[i][j][a][k])*(job_type_flatten[i][j][a] + (1-job_type_flatten[i][j][a])*tr[i])) #转换后的数据
                        sub_sub_sub_car_type.append(job_type_flatten[i][j][a])
                        sub_sub_sub_out_car.append(solver.Value(job_list[i][j][a][k]))
                        sub_sub_sub_job_re.append(copy.deepcopy(job_re_flatten[i][j][a]))
                        sub_sub_sub_job_re_r.append(copy.deepcopy(job_re_r_flatten[i][j][a]))
                if sum(sub_sub_sub_car) >0:
                    sub_sub_car.append(sub_sub_sub_car)
                    sub_sub_car_type.append(sub_sub_sub_car_type)
                    sub_sub_out_car.append(sub_sub_sub_out_car)
                    sub_sub_job_re.append(sub_sub_sub_job_re)
                    sub_sub_job_re_r.append(sub_sub_sub_job_re_r)
            sub_car.append(sub_sub_car)
            sub_car_type.append(sub_sub_car_type)
            sub_out_car.append(sub_sub_out_car)
            sub_job_re.append(sub_sub_job_re)
            sub_job_re_r.append(sub_sub_job_re_r)
        car.append(sub_car)
        car_type.append(sub_car_type)
        out_car.append(sub_out_car)
        job_re.append(sub_job_re)
        job_re_r.append(sub_job_re_r)



    store = []
    end_goods = []
    for i in range(len(goods)):
        sub_goods = []
        for j in range(len(goods[i])):
            for k in range(len(goods[i][j])):
                store += goods[i][j][k]
        sub_goods.append(store)
        store = []
        end_goods.append(sub_goods)


    ends_good_num = []
    for i in range(len(job_data)):
        sub_ends_good_num = []
        for j in range(len(job_data[i])):
            sub_sub_ends_good_num = []
            for k in range(len(job_data[i][j])):
                # sub_sub_sub_ends_good_num = [0]
                # for a in range(len(job_data[i][j][k])):
                #     sub_sub_sub_ends_good_num.append(0)
                sub_sub_ends_good_num.append(0)
            sub_ends_good_num.append(sub_sub_ends_good_num)
        ends_good_num.append(sub_ends_good_num)
    # -----------------------------------------------------------------------------------------------------------------------
    # 该段代码用于处理时间窗求解函数的输入，即对装车模型得到的装车数据进行处理

    goods_num_new = []
    job_total = []
    job_type_total = []
    car_goods_d = []
    for i in range(len(job_re)):  # 厂家层级遍历
        job_sub = []
        type_sub = []
        ss_goods_num = []
        sub_car_goods_d = []
        num = 0
        for j in range(len(job_re[i])):  # 订单层级遍历
            sub_ss_goods_num = []
            u_job_sub = []
            u_type_sub = []
            sub_sub_car_goods_d = []
            for q in range(len(job_re[i][j])):  # 车辆层级遍历
                e = 0
                m = 0
                g_0 = 0
                g_1 = 0
                sub_sub_ss_goods_num = []
                p_type = []
                type_sub_sub = []
                job_sub_sub = []
                sub_sub_sub_car_goods_d = []
                for k in range(len(job_re[i][j][q])):  # 订单详情层级遍历
                    if job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
                        job_re_r[i][j][q][k][3]] == 0:

                        num = int(car[i][j][q][k] / tr[i])
                        b_num = ends_good_num[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]]
                        m += int(car[i][j][q][k] / tr[i])  # 将一个车里的同一类货物累加起来
                        sub_sub_sub_car_goods_d.append(sum(goods[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]][b_num:b_num + num]))  # 得到订单详情的货物内部数量，方便后续计算
                        g_0 += sum(goods[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]][b_num:b_num + num])  # 累积同一辆车同一类型货物内部数量
                        p_type.append(0)  # 记录货物类型，方便判断
                        ends_good_num[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]] += num
                    elif job_type[job_re_r[i][j][q][k][0]][job_re_r[i][j][q][k][1]][job_re_r[i][j][q][k][2]][
                        job_re_r[i][j][q][k][3]] == 1:

                        num = car[i][j][q][k]  # 用作取货物内部数量的下标
                        b_num = ends_good_num[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]]
                        e += car[i][j][q][k]  # 将一个车里的同一类货物累加起来
                        sub_sub_sub_car_goods_d.append(sum(goods[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]][b_num:b_num + num]))  # 得到订单详情的货物内部数量，方便后续计算
                        g_1 += sum(goods[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]][b_num:b_num + num])  # 累积同一辆车同一类型货物内部数量
                        p_type.append(1)  # 记录货物类型，方便判断
                        ends_good_num[job_re[i][j][q][k][0]][job_re[i][j][q][k][1]][job_re[i][j][q][k][2]] += num
                if 1 in p_type:
                    type_sub_sub.append(1)
                    job_sub_sub.append(e)
                    sub_sub_ss_goods_num.append(g_1)

                if 0 in p_type:
                    type_sub_sub.append(0)
                    job_sub_sub.append(m)
                    sub_sub_ss_goods_num.append(g_0)

                sub_sub_car_goods_d.append(sub_sub_sub_car_goods_d)
                u_job_sub.append(job_sub_sub)
                u_type_sub.append(type_sub_sub)
                sub_ss_goods_num.append(sub_sub_ss_goods_num)
            sub_car_goods_d.append(sub_sub_car_goods_d)
            job_sub.append(u_job_sub)
            type_sub.append(u_type_sub)
            ss_goods_num.append(sub_ss_goods_num)
        car_goods_d.append(sub_car_goods_d)
        job_total.append(job_sub)
        job_type_total.append(type_sub)
        goods_num_new.append(ss_goods_num)


    no_car_re_temp = []
    no_car_type_temp = []
    no_out_car_temp = []



    for i in range(len(job_total)): #若所排的车辆数量大于给定数量则删除
        total_car_num = sum(car_num[i])
        car_num_check = 0
        for j in range(len(job_total[i])):
            for k in range(len(job_total[i][j])):
                if car_num_check < total_car_num:
                    car_num_check += 1
                else:
                    no_car_re_temp += job_re[i][j][k:len(job_re[i][j])]
                    no_out_car_temp += out_car[i][j][k:len(out_car[i][j])]
                    no_car_type_temp += car_type[i][j][k:len(car_type[i][j])]
                    del job_total[i][j][k:len(job_total[i][j])]
                    del job_type_total[i][j][k:len(job_type_total[i][j])]
                    del job_re[i][j][k:len(job_re[i][j])]
                    del goods_num_new[i][j][k:len(goods_num_new[i][j])]
                    del out_car[i][j][k:len(out_car[i][j])]
                    del car_type[i][j][k:len(car_type[i][j])]
                    del car_goods_d[i][j][k:len(car_goods_d[i][j])]
                    break

    no_car_re_temp = sum(no_car_re_temp, [])
    no_car_type_temp = sum(no_car_type_temp, [])
    no_out_car_temp = sum(no_out_car_temp, [])

    no_job_data_re_temp = [[no_car_type_temp[i] * no_out_car_temp[i], (1 - no_car_type_temp[i]) * no_out_car_temp[i]]
                           for i in range(len(no_car_re_temp))] #前件箱后栈板


    if no_car_re_temp != []: #返回未排的货物数据
        slow = 0
        temp = no_job_data_re_temp[0]
        for i in range(1, len(no_car_re_temp)):
            if no_car_re_temp[i] != no_car_re_temp[slow]:
                no_job_data_re.append(temp)
                no_car_re.append(no_car_re_temp[slow])
                temp = [0, 0]
                slow = i

            temp[0] += no_job_data_re_temp[i][0]
            temp[1] += no_job_data_re_temp[i][1]
        no_job_data_re.append(temp)
        no_car_re.append(no_car_re_temp[slow])



    return job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, no_car_re, no_job_data_re

def zz_process(job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, car_num):
    # 处理自制缺车的数据
    re = []

    for i in range(len(job_total)):
        total_car_num = sum(car_num[i])
        car_num_check = 0
        for j in range(len(job_total[i])):
            for k in range(len(job_total[i][j])):
                if car_num_check < total_car_num:
                    car_num_check += 1
                else:
                    del job_total[i][j][k:len(job_total[i][j])]
                    del job_type_total[i][j][k:len(job_type_total[i][j])]
                    re += job_re[i][j][k:len(job_re[i][j])][0]
                    del job_re[i][j][k:len(job_re[i][j])]
                    del goods_num_new[i][j][k:len(goods_num_new[i][j])]
                    del out_car[i][j][k:len(out_car[i][j])]
                    del car_type[i][j][k:len(car_type[i][j])]
                    del car_goods_d[i][j][k:len(car_goods_d[i][j])]
                    break

    return job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, re

def insert_sort_zz_time(zz_time_begin, zz_time_end, car_num,time_window,insert_time):
    '''
    自制车辆优先级预处理，后续算法会优先选择发车时间在时间窗内且晚于插单时间的车
    '''
    new_zz_time_begin, new_zz_time_end, new_car_num = [[]for _ in range(len(zz_time_begin))],[[]for _ in range(len(zz_time_end))],[[]for _ in range(len(car_num))]

    for i in range(len(zz_time_begin)):
        IND = [(idx,num) for idx,num in enumerate(zz_time_begin[i])]
        IND = sorted(IND,key=lambda x: x[1])
        before = []
        last = []
        for j in range(len(IND)):
            if IND[j][1]>=insert_time:
                flag_bl = False
                for q in range(len(time_window)):
                    if IND[j][1]>= time_window[q][0] and zz_time_end[i][IND[j][0]] <= time_window[q][1]:
                        flag_bl = True
                        break
                if IND[j][1] ==  zz_time_end[i][IND[j][0]]:
                    flag_bl = False
                if  flag_bl == True:
                    before.append(copy.deepcopy(IND[j][0]))
                else:
                    last.append(copy.deepcopy(IND[j][0]))
            else:
                last.append(copy.deepcopy(IND[j][0]))
        for k in range(len(before)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][before[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][before[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][before[k]]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))


    return new_car_num,new_zz_time_begin,new_zz_time_end

def sort_zz_time(zz_time_begin, zz_time_end, car_num,time_window):
    '''
    自制车辆优先级预处理，后续算法会优先选择发车时间在时间窗的车
    '''
    new_zz_time_begin, new_zz_time_end, new_car_num = [[]for _ in range(len(zz_time_begin))],[[]for _ in range(len(zz_time_end))],[[]for _ in range(len(car_num))]
    for i in range(len(zz_time_begin)):
        IND = [(idx,num) for idx,num in enumerate(zz_time_begin[i])]
        IND = sorted(IND,key=lambda x: x[1])
        before = []
        last = []
        for j in range(len(IND)):
            flag_bl = False
            for q in range(len(time_window)):
                if IND[j][1]>= time_window[q][0] and zz_time_end[i][IND[j][0]] <= time_window[q][1]:
                    flag_bl = True
                    break
            if  flag_bl == True:
                before.append(copy.deepcopy(IND[j][0]))
            else:
                last.append(copy.deepcopy(IND[j][0]))

        for k in range(len(before)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][before[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][before[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][before[k]]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))

    return new_car_num,new_zz_time_begin,new_zz_time_end

def insert_get_se_car_to_time(zz_car, zz_time_begin, zz_time_end, car_num,insert_time):
    '''
    该函数就是把处理后的自制发车表时间分配给排的自制车，在功能的实现上和get_se_car_to_time_before是一样的，但是得到的时间是经过time_window_process_se处理过的
    :param zz_car: 自制根据货物排的车
    :param zz_time_begin: 自制发车表的开始时间
    :param zz_time_end: 自制发车表的结束时间
    :param car_num: 自制发车表对应的车
    :return: car_time：得到自制排好的车对应的时间
    '''

    new_zz_time_begin, new_zz_time_end, new_car_num = [[]for _ in range(len(zz_time_begin))],[[]for _ in range(len(zz_time_end))],[[]for _ in range(len(car_num))]


    for i in range(len(zz_time_begin)):
        IND = [(idx,num) for idx,num in enumerate(zz_time_begin[i])]
        IND = sorted(IND,key=lambda x: x[1])
        before = []
        last = []
        for j in range(len(IND)):
            if IND[j][1]>insert_time:
                before.append(copy.deepcopy(IND[j][0]))
            else:
                last.append(copy.deepcopy(IND[j][0]))
        for k in range(len(before)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][before[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][before[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][before[k]]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))

        for j in range(len(IND)):
            last.append(copy.deepcopy(IND[j][0]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))

    car_index = []
    car_to_time = []
    for i in range(len(new_car_num)):
        sub_car_to_time = []
        sub_car_index = []
        car_num_re = 0
        for j in range(len(new_car_num[i])):
            car_num_re += new_car_num[i][j]
            sub_car_index.append(car_num_re)
            sub_car_to_time.append([new_zz_time_begin[i][j], new_zz_time_end[i][j]])
        car_to_time.append(sub_car_to_time)
        car_index.append(sub_car_index)

    car_time = []
    for i in range(len(zz_car)):
        car_time_sub = []
        index_num = 0
        zz_car_num = 0
        for j in range(len(zz_car[i])):
            car_time_sub_sub = []
            for k in range(len(zz_car[i][j])):
                if zz_car_num == car_index[i][index_num]:
                    index_num += 1
                car_time_sub_sub.append(car_to_time[i][index_num])
                zz_car_num += 1
            car_time_sub.append(car_time_sub_sub)
        car_time.append(car_time_sub)

    return car_time

def get_se_car_to_time(zz_car, zz_time_begin, zz_time_end, car_num):
    '''
    该函数就是把处理后的自制发车表时间分配给排的自制车，在功能的实现上和get_se_car_to_time_before是一样的，但是得到的时间是经过time_window_process_se处理过的
    :param zz_car: 自制根据货物排的车
    :param zz_time_begin: 自制发车表的开始时间
    :param zz_time_end: 自制发车表的结束时间
    :param car_num: 自制发车表对应的车
    :return: car_time：得到自制排好的车对应的时间
    '''

    car_index = []
    car_to_time = []
    for i in range(len(car_num)):
        sub_car_to_time = []
        sub_car_index = []
        car_num_re = 0
        for j in range(len(car_num[i])):
            car_num_re += car_num[i][j]
            sub_car_index.append(car_num_re)
            sub_car_to_time.append([zz_time_begin[i][j], zz_time_end[i][j]])
        car_to_time.append(sub_car_to_time)
        car_index.append(sub_car_index)

    car_time = []
    for i in range(len(zz_car)):
        car_time_sub = []
        index_num = 0
        zz_car_num = 0
        for j in range(len(zz_car[i])):
            car_time_sub_sub = []
            for k in range(len(zz_car[i][j])):
                if zz_car_num == car_index[i][index_num]:
                    index_num += 1
                car_time_sub_sub.append(car_to_time[i][index_num])
                zz_car_num += 1
            car_time_sub.append(car_time_sub_sub)
        car_time.append(car_time_sub)

    return car_time


def insert_get_se_car_to_time_before(zz_car, zz_time_begin, zz_time_end, car_num,insert_time):
    '''
    该函数用于得到还未经time_window_process_se函数处理过的自制发车时间，主要作用就是给排的自制车分配发车的开始时间和结束时间，然后方便get_end_zz_time函数的使用
    :param zz_car: 自制根据货物排的车
    :param zz_time_begin: 自制发车表的开始时间
    :param zz_time_end: 自制发车表的结束时间
    :param car_num: 自制发车表对应的车
    :return: car_time：得到自制排好的车对应的时间
    '''

    new_zz_time_begin, new_zz_time_end, new_car_num = [[]for _ in range(len(zz_time_begin))],[[]for _ in range(len(zz_time_end))],[[]for _ in range(len(car_num))]


    for i in range(len(zz_time_begin)):
        IND = [(idx,num) for idx,num in enumerate(zz_time_begin[i])]
        IND = sorted(IND,key=lambda x: x[1])
        before = []
        last = []
        for j in range(len(IND)):
            if IND[j][1]>insert_time:
                before.append(copy.deepcopy(IND[j][0]))
            else:
                last.append(copy.deepcopy(IND[j][0]))
        for k in range(len(before)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][before[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][before[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][before[k]]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))

        for j in range(len(IND)):
            last.append(copy.deepcopy(IND[j][0]))
        for k in range(len(last)):
            new_zz_time_begin[i].append(copy.deepcopy(zz_time_begin[i][last[k]]))
            new_zz_time_end[i].append(copy.deepcopy(zz_time_end[i][last[k]]))
            new_car_num[i].append(copy.deepcopy(car_num[i][last[k]]))

    car_index = []
    car_to_time = []
    for i in range(len(new_car_num)):
        sub_car_to_time = []
        sub_car_index = []
        car_num_re = 0
        for j in range(len(new_car_num[i])):
            car_num_re += new_car_num[i][j]
            sub_car_index.append(car_num_re)
            sub_car_to_time.append([new_zz_time_begin[i][j], new_zz_time_end[i][j]])
        car_to_time.append(sub_car_to_time)
        car_index.append(sub_car_index)

    car_time = []
    for i in range(len(zz_car)):
        car_time_sub = []
        index_num = 0
        zz_car_num = 0
        for j in range(len(zz_car[i])):
            car_time_sub_sub = []
            for k in range(len(zz_car[i][j])):
                if zz_car_num == car_index[i][index_num]:
                    index_num += 1
                car_time_sub_sub.append(car_to_time[i][index_num])
                zz_car_num += 1
            car_time_sub.append(car_time_sub_sub)
        car_time.append(car_time_sub)

    return car_time

def get_se_car_to_time_before(zz_car, zz_time_begin, zz_time_end, car_num):
    '''
    该函数用于得到还未经time_window_process_se函数处理过的自制发车时间，主要作用就是给排的自制车分配发车的开始时间和结束时间，然后方便get_end_zz_time函数的使用
    :param zz_car: 自制根据货物排的车
    :param zz_time_begin: 自制发车表的开始时间
    :param zz_time_end: 自制发车表的结束时间
    :param car_num: 自制发车表对应的车
    :return: car_time：得到自制排好的车对应的时间
    '''

    car_index = []
    car_to_time = []
    for i in range(len(car_num)):
        sub_car_to_time = []
        sub_car_index = []
        car_num_re = 0
        for j in range(len(car_num[i])):
            car_num_re += car_num[i][j]
            sub_car_index.append(car_num_re)
            sub_car_to_time.append([zz_time_begin[i][j], zz_time_end[i][j]])
        car_to_time.append(sub_car_to_time)
        car_index.append(sub_car_index)

    car_time = []
    for i in range(len(zz_car)):
        car_time_sub = []
        index_num = 0
        zz_car_num = 0
        for j in range(len(zz_car[i])):
            car_time_sub_sub = []
            for k in range(len(zz_car[i][j])):
                if zz_car_num == car_index[i][index_num]:
                    index_num += 1
                car_time_sub_sub.append(car_to_time[i][index_num])
                zz_car_num += 1
            car_time_sub.append(car_time_sub_sub)
        car_time.append(car_time_sub)

    return car_time

def se_solve(job_data, job_type, data_end_start, V_j, c, a_c, dis, zz_car_time, V_EMS_j, t, zz_interval_time, ems_c,
             rong_liang_zz, zhuan_hua_zz, box_flow_value, zz_delivery_count, ems_delivery_count, zz_priority, max_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger):
    """
    该函数用于求解时间窗，输入输出参数解释如下
    :param job_data:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，货物数量
    :param d_list:EMS货物的截止日期
    :param job_type:EMS货物形态 0可代表栈板，1代表件箱，2代表gtp；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，货物类型
    :param data_end_start:各个任务对应的开始时间
    :param V_j: 不同类型货物对应通道的速度，数量/秒，[栈板速度，自制速度，件箱速度]
    :param c:对应于自制的可用通道；维度1，维度2，维度3 =  厂家，订单，货物类型，通道类型和数量；[0,1]表示1楼，[1,0]表示-1楼； 第三个维度前件箱，后栈板；如 s_c = [[[[1, 0, 1, 0], [1, 1, 1]]], [[[0, 1], [1, 1, 1]]]]表示第一个厂家安排了负1楼件箱通道2个,栈板通道3个;第二个厂家安排了1楼件箱通道1个,栈板通道3个
    :param a_c:栈板的总通道数量
    :param t:求解时间，若最后无解，则需调大时间
    :param dis:打折系数
    :param V_EMS_j:输入到EMS求解的速度参数,单位:数量/秒，[栈板速度，件箱速度，自制速度]
    :param zz_car_time: 每辆车的开始和结束时间 维度1,维度2,维度3,维度4 = 厂家,订单,车辆，时间
    :param zz_interval_time:自制发车间隔时间
    :param c:对应于EMS的可用通道；维度1，维度2，维度3，维度4 = 厂家，订单，通道类型，通道 ；通道类型中前一个维度都是件箱的，后一个维度都是栈板的，如c = [[[[1, 1, 1, 1], [1, 1]]]]中[1, 1, 1, 1]表示件箱可用的通道，[1,1]表示栈板可用的通道
    :param rong_liang_zz:对应于厂家的车辆容量，只有一个维度(自制)
    :param zhuan_hua_zz:对应于厂家的转换系数，只有一个维度(自制)
    :param box_flow_value:最大流量限制
    :param zz_delivery_count:最大自制通道限制
    :param ems_delivery_count:最大ems通道限制
    :param max_time:归一化后所有时间戳相关参数的最大时间
    :return: solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为秒，维度1,维度2,维度3,维度4 = 厂家,订单,车辆，时间
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，是否被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，通道号
    solution_bool_C_N 方便EMS求解使用的通道参数；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，通道号
    total_C_list:货物是否被安排在某个通道中
    j_sub_p_s:某个货物在时间窗内的开始时间
    j_sub_p_e:某个货物在时间窗内的结束时间
    j_sub_p_e_1：某个货物在时间窗内的时间间隔
    """

    # # 对速度进行折扣处理
    # for v in range(len(V_j)):
    #     if int(V_j[v] * dis) != 0:
    #         V_j[v] = int(V_j[v] * dis)
    #     else:
    #         V_j[v] = 1
    # # 对速度进行折扣处理
    # for v in range(len(V_EMS_j)):
    #     if int(V_EMS_j[v] * dis) != 0:
    #         V_EMS_j[v] = int(V_EMS_j[v] * dis)
    #     else:
    #         V_EMS_j[v] = 1
    total_zz_cargo_num,total_ems_cargo_num = get_zz_cargo_num(job_data,job_type,c)

    # 对速度进行折扣处理
    for v in range(len(V_j)):
        V_j[v] = int(V_j[v] * dis * 10000)#求解器只能求解整形，先取整，乘大数是为了增加后续速度计算的精度

    # 对速度进行折扣处理
    for v in range(len(V_EMS_j)):
        V_EMS_j[v] = int(V_EMS_j[v] * dis * 10000)#求解器只能求解整形，先取整，乘大数是为了增加后续速度计算的精度

    total_C_list = []
    bool_job_list = []
    bool_sub_job_list = []
    job_p_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    solution_bool_C_N = []
    de = []

    rs_c = []
    rs_zz_delivery_count = []
    rs_ems_delivery_count = []
    total_bb = 0
    total_bbb = 0

    model = cp_model.CpModel()

    for i in range(len(job_data)):  # 厂家层级遍历
        j_b = model.NewBoolVar('%d' % i)  # 该厂家的车是否全部排完
        total_bb += j_b
        bool_job_list.append(j_b)
        job_p_sub = []
        C_list = []
        bool_sub_job = []
        bool_sub_ssub_job = []
        ems_c_num_occupy = [[] for _ in range(len(random_ems_index))]
        zz_c_num_occupy = [[] for _ in range(len(random_zz_index))]
        ems_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_ems_index))]
        zz_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_zz_index))]
        ems_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_ems_index))]
        zz_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_zz_index))]
        for j in range(len(job_data[i])):  # 订单层级的遍历
            j_sub_b = model.NewBoolVar('%d_%d' % (i, j))  # 订单是否完成
            bool_sub_job.append(j_sub_b)
            u_bool_sub_sub_job = []
            u_job_p_sub_sub = []
            u_sub_C_list = []
            u_bool_sub_job_se = []


            for k in range(len(job_data[i][j])):  # 车辆层级遍历
                u_j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))  # 车辆是否排入
                u_bool_sub_job_se.append(u_j_sub_b_se)
                bool_sub_sub_job = []
                job_p_sub_sub = []
                sub_C_list = []
                for p in range(len(job_data[i][j][k])):  # 车内部货物类型层级遍历（件箱、栈板）
                    j_sub_sub_b = model.NewBoolVar('%d_%d_%d_%d' % (i, j, k, p))  # 货物是否被分配通道并在交期内处理
                    bool_sub_sub_job.append(j_sub_sub_b)
                    total_bbb += j_sub_sub_b
                    sub_sub_c_list = []
                    sub_sub_p_list = []
                    j_sub_p_s = model.NewIntVar(zz_car_time[i][j][k][0], max_time,
                                                'p_s_%d_%d_%d_%d' % (i, j, k, p))  # 货物开始处理时间变量
                    j_sub_p_e = model.NewIntVar(zz_car_time[i][j][k][0], max_time,
                                                'p_e_%d_%d_%d_%d' % (i, j, k, p))  # 货物结束处理时间变量
                    j_sub_p_e_1 = model.NewIntVar(zz_car_time[i][j][k][0], max_time,
                                                  'p_e1_%d_%d_%d_%d' % (i, j, k, p))  # 用于车辆时间间隔的变量
                    due_data_d = model.NewBoolVar('due_data_d')  # 交期是否满足的变量
                    c_d = model.NewBoolVar('c_d')  # 是否分配通道的变量
                    model.Add(j_sub_p_e <= zz_car_time[i][j][k][1]).OnlyEnforceIf(due_data_d)  # 交期约束
                    model.Add(j_sub_p_e > zz_car_time[i][j][k][1]).OnlyEnforceIf(due_data_d.Not())  # 交期约束
                    sub_sub_p_list.append(j_sub_p_s)
                    sub_sub_p_list.append(j_sub_p_e)
                    sub_sub_p_list.append(j_sub_p_e_1)
                    job_p_sub_sub.append(sub_sub_p_list)
                    if job_type[i][j][k][p] == 0:  # 根据货物类型来查询通道
                        for v in range(len(c[i][j][1])):  # 遍历通道
                            if c[i][j][1][v] == 1:  # 通道可以使用，为0则是被禁用
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, 7))
                                sub_sub_c_list.append(b)
                    else:
                        # 自制件箱的通道有些特殊，自制的通道分为去一楼的和去负一楼的，一楼的通道坏了，现在和EMS的通道共享
                        if c[i][j][0][0] == 1:  # 去负一楼的通道，不用和EMS共享
                            for m in range(len(c[i][j][0])):
                                if c[i][j][0][m] == 1:
                                    b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                    sub_sub_c_list.append(b)
                                    zz_c_num_occupy[m//2].append(b)
                        else:  # 去一楼的，得和EMS共享
                            # cc = [1, 1, 1, 1, 1, 1, 1]
                            cc = ems_c[0][0][0]
                            for m in range(len(cc)):
                                if cc[m] == 1:
                                    b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                    sub_sub_c_list.append(b)
                                    ems_c_num_occupy[m].append(b)

                    model.Add(sum(sub_sub_c_list) <= job_data[i][j][k][p])
                    model.Add(sum(sub_sub_c_list) > 0).OnlyEnforceIf(c_d)  # 分配通道，c_d为1
                    model.Add(sum(sub_sub_c_list) == 0).OnlyEnforceIf(c_d.Not())
                    # model.Add(due_data_d == 1).OnlyEnforceIf(c_d)
                    model.Add(c_d + due_data_d == 2).OnlyEnforceIf(j_sub_sub_b)  # 交期通道两个全满足，货物进去
                    model.Add(c_d + due_data_d < 2).OnlyEnforceIf(j_sub_sub_b.Not())
                    sub_C_list.append(sub_sub_c_list)
                u_job_p_sub_sub.append(job_p_sub_sub)
                u_sub_C_list.append(sub_C_list)
                u_bool_sub_sub_job.append(bool_sub_sub_job)
                model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(
                    u_j_sub_b_se)  # 件箱和栈板全部排入或件箱、栈板排入就代表车排入了
                model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se.Not())



            model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b)  # 车全排入了，就代表订单完成了
            model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b.Not())

            C_list.append(u_sub_C_list)
            bool_sub_ssub_job.append(u_bool_sub_sub_job)
            job_p_sub.append(u_job_p_sub_sub)


        if c[i][0][0][0] == 0:
            if total_ems_cargo_num[i] >0:
                [model.Add(ems_c_occupy_s[v] == sum(ems_c_num_occupy[v])) for v in range(len(ems_c_occupy_s))]
                for v in range(len(ems_c_occupy)):
                    model.Add(ems_c_occupy_s[v] > 0).OnlyEnforceIf(ems_c_occupy[v])
                    model.Add(ems_c_occupy_s[v] <= 0).OnlyEnforceIf(ems_c_occupy[v].Not())
                if total_ems_cargo_num[i] < portEmsLpnNum2:
                    model.Add(sum(ems_c_occupy) <= 1)
                elif total_ems_cargo_num[i] >= portEmsLpnNum2 and total_ems_cargo_num[i] <= portEmsLpnNum3:
                    model.Add(sum(ems_c_occupy) <= 2)
                elif total_ems_cargo_num[i] > portEmsLpnNum3:
                    model.Add(sum(ems_c_occupy) <= 3)
        else:
            if total_zz_cargo_num[i] >0:
                [model.Add(zz_c_occupy_s[v] == sum(zz_c_num_occupy[v])) for v in range(len(zz_c_occupy_s))]
                for v in range(len(zz_c_occupy)):
                    model.Add(zz_c_occupy_s[v] > 0).OnlyEnforceIf(zz_c_occupy[v])
                    model.Add(zz_c_occupy_s[v] <= 0).OnlyEnforceIf(zz_c_occupy[v].Not())
                if total_zz_cargo_num[i] < portSelfLpnNum2:
                    model.Add(sum(zz_c_occupy) <= 1)
                elif total_zz_cargo_num[i] >= portSelfLpnNum2:
                    model.Add(sum(zz_c_occupy) <= 2)

        model.Add(sum(bool_sub_job) == len(bool_sub_job)).OnlyEnforceIf(j_b)  # 所有订单完成了，厂家完成了
        model.Add(sum(bool_sub_job) < len(bool_sub_job)).OnlyEnforceIf(j_b.Not())

        total_C_list.append(C_list)
        bool_sub_job_list.append(bool_sub_ssub_job)
        job_p_list.append(job_p_sub)

    # 接下来分配通达，并计算运输时间
    for i in range(len(job_data)):  # 厂家层级遍历
        for j in range(len(job_data[i])):  # 订单层级遍历
            x_tt_intervals = []
            for e in range(len(job_data[i][j])):  # 车辆遍历
                ini = []
                cd = []
                mm_v = model.NewIntVar(0, max_time, 'p_e_%d_%d' % (i, j))
                for p in range(len(job_data[i][j][e])):  # 货物类型遍历
                    total_interval = 0  # 速度总和的变量
                    if job_type[i][j][e][p] == 1 and c[i][j][0][0] == 0:  # 和EMS共享通道
                        for k in range(len(total_C_list[i][j][e][p])):
                            total_interval += total_C_list[i][j][e][p][k] * V_EMS_j[1]
                    else:
                        for k in range(len(total_C_list[i][j][e][p])):  # 去负一楼
                            total_interval += total_C_list[i][j][e][p][k] * V_j[job_type[i][j][e][p]]
                    t_i = model.NewIntVar(1, 99999999, 't_i_%d' % j)
                    model.Add(t_i == total_interval + 1)  # 速度计算待处理
                    I = model.NewIntVar(0, 99999999, 'In_%d' % j)
                    model.AddDivisionEquality(I, job_data[i][j][e][p] * 10000, t_i)
                    ini.append(job_p_list[i][j][e][p][0])
                    cd.append(I)

                    kk = 0
                    if job_type[i][j][e][p] == 1:  # 件箱货物形态
                        if c[i][j][0][0] == 1:  # 去负一楼
                            for u in range(len(c[i][j][0])):
                                if c[i][j][0][u] == 1:  # 通道可用，构建矩形
                                    y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, u))
                                    j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                     job_p_list[i][j][e][p][1],
                                                                                     total_C_list[i][j][e][p][u // 2],
                                                                                     'p_%d_%d_%d_%d' % (
                                                                                     i, j, p, u // 2))

                                    j_sub_c_intervals = model.NewOptionalIntervalVar(a_c + u, 1, y_end,
                                                                                     total_C_list[i][j][e][p][u // 2],
                                                                                     'c_%d_%d_%d_%d' % (
                                                                                     i, j, p, u // 2))

                                    kk += 1
                                    rs_c.append(j_sub_p_intervals) #最大容量约束
                                    rs_zz_delivery_count.append(j_sub_p_intervals) #最大自制通道约束
                                    de.append(int(V_j[2]))
                                    x_intervals.append(j_sub_p_intervals)
                                    y_intervals.append(j_sub_c_intervals)
                        else:  # 和EMS共享
                            # ccc = [1, 1, 1, 1, 1, 1, 1]  # 需修改，待处理
                            ccc = ems_c[0][0][0]
                            for u in range(len(ccc)):
                                if ccc[u] == 1:  # 通道可用，构建矩形
                                    y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, u))
                                    j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                     job_p_list[i][j][e][p][1],
                                                                                     total_C_list[i][j][e][p][u],
                                                                                     'p_%d_%d_%d_%d' % (i, j, p, u))

                                    j_sub_c_intervals = model.NewOptionalIntervalVar(a_c + u + 1, 1, y_end,
                                                                                     total_C_list[i][j][e][p][u],
                                                                                     'c_%d_%d_%d_%d' % (i, j, p, u))
                                    kk += 1
                                    rs_c.append(j_sub_p_intervals) #最大容量约束
                                    rs_ems_delivery_count.append(j_sub_p_intervals) #最大ems通道约束
                                    de.append(int(V_j[1]))
                                    x_intervals.append(j_sub_p_intervals)
                                    y_intervals.append(j_sub_c_intervals)

                    else:  # 栈板货物形态
                        for u in range(len(c[i][j][1])):
                            if c[i][j][1][u] == 1:  # 口可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))

                                j_sub_c_intervals = model.NewOptionalIntervalVar(u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                if len(ini) == 2:  # 若一辆车有两种类型的货物
                    model.Add(ini[0] == ini[1])  # 限制开始处理时间相同
                    model.Add(bool_sub_job_list[i][j][e][0] == bool_sub_job_list[i][j][e][1])
                    I_v = model.NewIntVar(0, 99999999, 'p_e_%d_%d' % (i, j))
                    model.AddMaxEquality(I_v, cd)
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], I_v + int(zz_interval_time[i]) + 1, mm_v,
                                                                       bool_sub_job_list[i][j][e][0],
                                                                       '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)
                else:
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], cd[0] + int(zz_interval_time[i]) + 1,
                                                                       mm_v,
                                                                       bool_sub_job_list[i][j][e][0],
                                                                       '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)

            model.AddNoOverlap(x_tt_intervals)

    load_rate = []

    for i in range(len(job_data)): #计算装载率
        sub_load_rate = []
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                total_goods = 0
                for p in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][p] == 0:
                        total_goods += job_data[i][j][k][p] * zhuan_hua_zz[i]
                    else:
                        total_goods += job_data[i][j][k][p]
                sub_load_rate.append(total_goods / rong_liang_zz[i])
        load_rate.append(sub_load_rate)

    load_rate_index = []

    for i in range(len(load_rate)):
        sub_load_rate = sorted(enumerate(load_rate[i]), key=lambda x: x[1], reverse=True)
        sub_load_index = [ind for ind, _ in sub_load_rate]
        load_rate_index.append(sub_load_index)

    for i in range(len(load_rate_index)):    # 装载率高的优先排前面
        if len(load_rate_index[i]) > 1:
            for k in range(len(load_rate_index[i]) - 1):
                model.Add(
                    job_p_list[i][0][load_rate_index[i][k]][0][0] < job_p_list[i][0][load_rate_index[i][k + 1]][0][0])

    # for i in range(len(job_p_list)):
    #     for j in range(len(job_p_list[i])):
    #         if len(job_p_list[i][j]) > 1:
    #             for k in range(len(job_p_list[i][j]) - 1):
    #                 model.Add(job_p_list[i][j][k][0][0] < job_p_list[i][j][k + 1][0][0])

    de_zz_delivery_count = [1] * len(rs_zz_delivery_count)
    de_ems_delivery_count = [1] * len(rs_ems_delivery_count)
    model.AddNoOverlap2D(x_intervals, y_intervals)
    model.AddCumulative(rs_c, de, int(10000 * dis * box_flow_value))  #最大容量约束
    model.AddCumulative(rs_zz_delivery_count, de_zz_delivery_count, zz_delivery_count)  #最大自制通道约自制
    model.AddCumulative(rs_ems_delivery_count, de_ems_delivery_count, ems_delivery_count)  #最大ems通道约束


    # priority_index = sorted(zz_priority)
    # car_first_start_time = []
    # for i in range(len(job_p_list)):
    #     sub_car_first_start_time = []
    #     for j in range(len(job_p_list[i])):
    #         for k in range(len(job_p_list[i][j])):
    #             sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
    #     car_first_start_time.append(sub_car_first_start_time)

    # for i in range(len(car_first_start_time) - 1):
    #     first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % i)
    #     next_first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % (i + 1))
    #     model.AddMinEquality(first_start_time, car_first_start_time[i])
    #     model.AddMinEquality(next_first_start_time, car_first_start_time[i + 1])
    #     model.Add(first_start_time <= next_first_start_time)

    # priority_index = sorted(zz_priority)
    # car_first_start_time = []
    # for i in range(len(job_p_list)):
    #     sub_car_first_start_time = []
    #     for j in range(len(job_p_list[i])):
    #         for k in range(len(job_p_list[i][j])):
    #             sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
    #     car_first_start_time.append(sub_car_first_start_time)
    #
    # left = 0
    # for i in range(1,len(car_first_start_time)):
    #     if(priority_index[i]>priority_index[i-1]):
    #         for j in range(left,i):
    #             first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % i)
    #             next_first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % (i + 1))
    #             model.AddMinEquality(first_start_time, car_first_start_time[j])
    #             model.AddMinEquality(next_first_start_time, car_first_start_time[i])
    #             model.Add(first_start_time <= next_first_start_time)
    #         left = i

    model.Maximize(total_bbb)  # 最大化排进去的车
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8

    solver.parameters.max_time_in_seconds = t
    solver.parameters.random_seed = 0
    status = solver.Solve(model)

    # 得到最终的解
    solution_find = False
    if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
        solution_find = True
        if status == cp_model.OPTIMAL:
            logger.info("自制时间窗模型求得最优解")
        if status == cp_model.FEASIBLE:
            logger.info("自制时间窗模型求得次优解")
    if solution_find == False:
        logger.error("自制时间窗模型无解")

    for i in range(len(job_data)):  # 厂家层级遍历
        solu_x_sub = []
        for j in range(len(job_data[i])):  # 订单层级遍历
            u_solu_x_sub = []
            for g in range(len(job_data[i][j])):  # 车辆层级遍历
                so = []
                for k in range(len(job_data[i][j][g])):  # 货物层级遍历
                    solution_x = []
                    if not solution_find: #无解则用0填充解
                        solution_x.append(0)
                        solution_x.append(0)
                    else:
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][0]))
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][1]))
                    so.append(solution_x)
                u_solu_x_sub.append(so)
            solu_x_sub.append(u_solu_x_sub)
        solution_x_total.append(solu_x_sub)

    for i in range(len(job_data)):  # 厂家层级遍历
        solu_bool_sub = []
        for j in range(len(job_data[i])):   # 订单层级遍历
            u_solu_bool_sub = []
            for g in range(len(job_data[i][j])):  # 车辆层级遍历
                so = []
                for k in range(len(job_data[i][j][g])):  # 货物层级遍历
                    if not solution_find: #无解则用0填充最后解
                        so.append(0)
                    else:
                        so.append(solver.Value(bool_sub_job_list[i][j][g][k]))
                u_solu_bool_sub.append(so)
            solu_bool_sub.append(u_solu_bool_sub)
        solution_bool_sub_job.append(solu_bool_sub)

    for i in range(len(job_data)): # 厂家层级遍历
        solu_C_sub = []
        for j in range(len(job_data[i])): # 订单层级遍历
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])): # 车辆层级遍历
                u_solu_C_sub_sub = []
                if len(job_data[i][j][e]) == 2:
                    so = []
                    c_index_list = []
                    for p in range(len(job_data[i][j][e])): # 货物层级遍历
                        # so = []
                        if job_type[i][j][e][p] == 1:
                            c_index_list.append(p)

                        # if job_type[i][j][e][p] == 0:
                        #     c_index_list.append(p)

                    for p in range(len(job_data[i][j][e])):
                        # so = []
                        # if job_type[i][j][e][p] == 1:
                        #     c_index_list.append(p)

                        if job_type[i][j][e][p] == 0:
                            c_index_list.append(p)

                    for w in range(len(total_C_list[i][j][e][c_index_list[0]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[0]][w]))

                    if (c[i][0][0][0] == 0):
                        so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                    else:
                        so = copy.deepcopy([so[random_zz_index[i]] for i in range(len(random_zz_index))])

                    for w in range(len(total_C_list[i][j][e][c_index_list[1]])):
                        if not solution_find:#无解则用0填充最后解
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[1]][w]))



                    u_solu_C_sub_sub.append(so)

                else:
                    so = []
                    if job_type[i][j][e][0] == 1:  # 如果是件箱
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:#无解则用0填充最后解
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        if (c[i][0][0][0] == 0):
                            so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                        else:
                            so = copy.deepcopy([so[random_zz_index[i]] for i in range(len(random_zz_index))])

                        so = so + [0] * len(c[0][0][1])
                        u_solu_C_sub_sub.append(so)
                    else:  # 如果是栈板
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:#无解则用0填充最后解
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        if (c[i][0][0][0] == 1):
                            so = [0] * (len(c[i][0][0]) // 2) + so
                        else:
                            so = [0] * len(ems_c[0][0][0]) + so
                        u_solu_C_sub_sub.append(so)
                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C.append(solu_C_sub)

    for i in range(len(job_data)): # 厂家层级遍历
        solu_C_sub = []
        for j in range(len(job_data[i])): # 订单层级遍历
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])): # 车辆层级遍历
                u_solu_C_sub_sub = []
                for p in range(len(job_data[i][j][e])): # 货物层级遍历
                    so = []
                    k = 0
                    if job_type[i][j][e][p] == 1:
                        for w in range(len(total_C_list[i][j][e][p])):
                            if not solution_find:#无解则用0填充最后解
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][p][w]))

                    else:
                        for z in range(len(c[i][j][1])):
                            if c[i][j][1][z] == 1:
                                if not solution_find:#无解则用0填充最后解
                                    so.append(0)
                                else:
                                    so.append(solver.Value(total_C_list[i][j][e][p][k]))
                                k += 1
                            else:
                                so.append(0)
                    u_solu_C_sub_sub.append(so)
                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C_N.append(solu_C_sub)

    return solution_x_total, solution_bool_sub_job, solution_bool_C, solution_bool_C_N


def solve(job_data, d_list, job_type, data_end_start, sxt, sbsj, sbc, s_job_type, V_j, s_c, c, p_num, a_c, dis, t,
          ems_interval_time, rong_liang_EMS, zhuan_hua_EMS, box_flow_value, zz_delivery_count, ems_delivery_count,
          ems_priority, max_time,work_time_list, interval_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger):
    """
    该函数用于求解时间窗，输入输出参数解释如下
    :param job_data:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
    :param d_list:EMS货物的截止日期
    :param job_type:EMS货物形态 0可代表栈板，1代表件箱，2代表gtp
    :param data_end_start:各个任务对应的开始时间
    :param sxt:所有自制子任务的开始处理时间和处理结束时间，单位为秒，维度1,维度2,维度3,维度4 = 厂家,订单,车辆，时间
    :param sbsj:该项对应某一个自制子任务是否被处理，若为1则被处理，若为0则没被处理；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，是否被处理
    :param sbc:方便EMS求解使用的通道参数；维度1,维度2,维度3,维度4 = 厂家,订单,车辆，通道号
    :param s_job_type: 每辆车装的总货物类型；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物类型
    :param V_j: 不同类型货物对应通道的速度，数量/秒，0的位置对应栈板，1的位置对应件箱，2的位置对应自制
    :param s_c:对应于自制的可用通道；维度1，维度2，维度3 =  厂家，订单，货物类型，通道类型和数量；[0,1]表示1楼，[1,0]表示-1楼； 第三个维度前件箱，后栈板；如 s_c = [[[[1, 0, 1, 0], [1, 1, 1]]], [[[0, 1], [1, 1, 1]]]]表示第一个厂家安排了负1楼件箱通道2个,栈板通道3个;第二个厂家安排了1楼件箱通道1个,栈板通道3个
    :param c: 可用的通道
    :param p_num: 所有件箱的通道
    :param a_c: 所有栈板的通道
    :param t:求解时间，若最后无解，则需调大时间
    :param dis:打折系数
    :param ems_interval_time:ems间隔时间
    :param rong_liang_EMS:ems最大容量
    :param zhuan_hua_EMS:ems转化系数
    :param box_flow_value:最大流量
    :param zz_delivery_count:最大自制通道限制
    :param ems_delivery_count:最大ems通道限制
    :param max_time:归一化后所有时间戳相关参数的最大时间
    :param interval_time:ems发车间隔时间
    :param ems_priority: ems优先级
    :return: solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为分钟
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    """
    # # 对速度进行折扣处理
    # for v in range(len(V_j)):
    #     if int(V_j[v] * dis) != 0:
    #         V_j[v] = int(V_j[v] * dis)
    #     else:
    #         V_j[v] = 1

    total_ems_cargo_num = get_ems_cargo_num(job_data, job_type)


    # 对速度进行折扣处理
    for v in range(len(V_j)):
        V_j[v] = int(V_j[v] * dis * 10000)

    total_C_list = []
    bool_job_list = []
    bool_sub_job_list = []
    job_p_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    rs_zz_delivery_count = []
    rs_ems_delivery_count = []
    de = []
    rs_c = []
    min_end_time = []
    total_bb = 0
    total_bbb = 0

    model = cp_model.CpModel()



    for i in range(len(job_data)):  # 厂家层级遍历
        ts = data_end_start[i]
        j_b = model.NewBoolVar('%d' % i)  # 该厂家的车是否全部排完
        total_bb += j_b
        bool_job_list.append(j_b)
        job_p_sub = []
        C_list = []
        bool_sub_job = []
        bool_sub_ssub_job = []
        ems_c_num_occupy = [[] for _ in range(len(random_ems_index))]
        ems_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_ems_index))]
        ems_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_ems_index))]

        for j in range(len(job_data[i])):  # 订单层级的遍历
            j_sub_b = model.NewBoolVar('%d_%d' % (i, j))  # 订单是否完成
            bool_sub_job.append(j_sub_b)
            u_bool_sub_sub_job = []
            u_job_p_sub_sub = []
            u_sub_C_list = []
            u_bool_sub_job_se = []



            for k in range(len(job_data[i][j])):  # 车辆层级遍历
                u_j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))
                u_bool_sub_job_se.append(u_j_sub_b_se)

                bool_sub_sub_job = []
                job_p_sub_sub = []
                sub_C_list = []
                for p in range(len(job_data[i][j][k])):  # 车内部货物类型层级遍历（件箱、栈板）
                    j_sub_sub_b = model.NewBoolVar('%d_%d_%d_%d' % (i, j, k, p))  # 货物是否被分配通道并在交期内处理
                    bool_sub_sub_job.append(j_sub_sub_b)
                    total_bbb += j_sub_sub_b
                    sub_sub_c_list = []
                    sub_sub_p_list = []
                    j_sub_p_s = model.NewIntVar(ts, max_time, 'p_s_%d_%d_%d_%d' % (i, j, k, p))  # 货物开始处理时间变量
                    j_sub_p_e = model.NewIntVar(ts, max_time, 'p_e_%d_%d_%d_%d' % (i, j, k, p))  # 货物结束处理时间变量
                    j_sub_p_e_1 = model.NewIntVar(ts, max_time, 'p_e1_%d_%d_%d_%d' % (i, j, k, p))  # 用于车辆时间间隔的变量
                    min_end_time.append(j_sub_p_e)
                    due_data_d = model.NewBoolVar('due_data_d')  # 交期是否满足的变量
                    c_d = model.NewBoolVar('c_d')  # 是否分配通道的变量
                    model.Add(j_sub_p_e <= d_list[i]).OnlyEnforceIf(due_data_d)  # 交期约束
                    model.Add(j_sub_p_e > d_list[i]).OnlyEnforceIf(due_data_d.Not())  # 交期约束
                    sub_sub_p_list.append(j_sub_p_s)
                    sub_sub_p_list.append(j_sub_p_e)
                    sub_sub_p_list.append(j_sub_p_e_1)
                    job_p_sub_sub.append(sub_sub_p_list)
                    if job_type[i][j][k][p] == 0:  # 根据货物类型来查询通道
                        for v in range(len(c[i][j][1])):  # 遍历通道
                            if c[i][j][1][v] == 1:  # 通道可以使用，为0则是被禁用
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, 7))
                                sub_sub_c_list.append(b)
                    else:
                        for m in range(len(c[i][j][0])):
                            if c[i][j][0][m] == 1:
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                sub_sub_c_list.append(b)
                                ems_c_num_occupy[m].append(b)
                    model.Add(sum(sub_sub_c_list) <= job_data[i][j][k][p])
                    model.Add(sum(sub_sub_c_list) > 0).OnlyEnforceIf(c_d)  # 分配通道，c_d为1
                    model.Add(sum(sub_sub_c_list) == 0).OnlyEnforceIf(c_d.Not())
                    # model.Add(due_data_d == 1).OnlyEnforceIf(c_d)
                    model.Add(c_d + due_data_d == 2).OnlyEnforceIf(j_sub_sub_b)  # 交期通道两个全满足，货物进去
                    model.Add(c_d + due_data_d < 2).OnlyEnforceIf(j_sub_sub_b.Not())
                    sub_C_list.append(sub_sub_c_list)
                u_job_p_sub_sub.append(job_p_sub_sub)
                u_sub_C_list.append(sub_C_list)
                u_bool_sub_sub_job.append(bool_sub_sub_job)
                model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(
                    u_j_sub_b_se)  # 件箱和栈板全部排入或件箱、栈板排入就代表车排入了
                model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se.Not())


            model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b)  # 车全排入了，就代表订单完成了
            model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b.Not())

            C_list.append(u_sub_C_list)
            bool_sub_ssub_job.append(u_bool_sub_sub_job)
            job_p_sub.append(u_job_p_sub_sub)
            # model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b)
            # model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b.Not())

        if total_ems_cargo_num[i] > 0:
            [model.Add(ems_c_occupy_s[v] == sum(ems_c_num_occupy[v])) for v in range(len(ems_c_occupy_s))]
            for v in range(len(ems_c_occupy)):
                model.Add(ems_c_occupy_s[v] > 0).OnlyEnforceIf(ems_c_occupy[v])
                model.Add(ems_c_occupy_s[v] <= 0).OnlyEnforceIf(ems_c_occupy[v].Not())
            if total_ems_cargo_num[i] <= portEmsLpnNum2:
                model.Add(sum(ems_c_occupy) <= 1)
            if total_ems_cargo_num[i] > portEmsLpnNum2 and total_ems_cargo_num[i] <= portEmsLpnNum3:
                model.Add(sum(ems_c_occupy) <= 2)
            if total_ems_cargo_num[i] >= portEmsLpnNum3:
                model.Add(sum(ems_c_occupy) <= 3)

        model.Add(sum(bool_sub_job) == len(bool_sub_job)).OnlyEnforceIf(j_b)  # 所有订单完成了，厂家完成了
        model.Add(sum(bool_sub_job) < len(bool_sub_job)).OnlyEnforceIf(j_b.Not())

        total_C_list.append(C_list)
        bool_sub_job_list.append(bool_sub_ssub_job)
        job_p_list.append(job_p_sub)

    # 之前自制的求解，在此处作为常数矩形
    for g in range(len(sxt)):
        for i in range(len(sxt[g])):
            for k in range(len(sxt[g][i])):
                for p in range(len(sxt[g][i][k])):
                    if s_job_type[g][i][k][p] == 1:  # 如果是件箱
                        if s_c[g][0][0][0] == 1:  # 负一楼
                            for l in range(len(sbc[g][i][k][p])):
                                if sbc[g][i][k][p][l]:  # 如果通道启用
                                    x_s = model.NewConstant(sxt[g][i][k][p][0])
                                    ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                    x_e = model.NewConstant(sxt[g][i][k][p][1])
                                    y_s = model.NewConstant(l + p_num + a_c)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(l + p_num + a_c + 1)
                                    if sbsj[g][i][k][p] == 1:
                                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p],
                                                                            'x_ii%d' % i)
                                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p],
                                                                            'y_ii%d' % i)
                                        x_intervals.append(x_ii)
                                        y_intervals.append(y_ii)
                                        de.append(V_j[2])
                                        rs_c.append(x_ii)
                                        rs_zz_delivery_count.append(x_ii)
                        else:  # 一楼，与ems共享
                            for l in range(len(sbc[g][i][k][p])):
                                if sbc[g][i][k][p][l]:
                                    x_s = model.NewConstant(sxt[g][i][k][p][0])
                                    ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                    x_e = model.NewConstant(sxt[g][i][k][p][1])
                                    y_s = model.NewConstant(l)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(l + 1)
                                    if sbsj[g][i][k][p] == 1:
                                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p],
                                                                            'x_ii%d' % i)
                                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p],
                                                                            'y_ii%d' % i)
                                        x_intervals.append(x_ii)
                                        y_intervals.append(y_ii)
                                        de.append(V_j[1])
                                        rs_c.append(x_ii)
                                        rs_ems_delivery_count.append(x_ii)
                    else:
                        for l in range(len(sbc[g][i][k][p])):
                            if sbc[g][i][k][p][l]:
                                x_s = model.NewConstant(sxt[g][i][k][p][0])
                                ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                x_e = model.NewConstant(sxt[g][i][k][p][1])
                                y_s = model.NewConstant(l + p_num)
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(l + p_num + 1)
                                if sbsj[g][i][k][p] == 1:
                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p], 'x_ii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p], 'y_ii%d' % i)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)

    # 接下来分配通达，并计算运输时间
    x_tt_ems_itv = []
    x_tt_itv2 = []
    x_tt_itv3 = []
    x_tt_ini = []
    x_tt_mmv = []
    x_tt_is_bool_var = []
    x_tt_cd = []
    for i in range(len(job_data)):  # 厂家层级遍历
        for j in range(len(job_data[i])):  # 订单层级遍历
            x_tt_intervals = []
            for e in range(len(job_data[i][j])):  # 车辆遍历
                ini = []
                cd = []
                mm_v = model.NewIntVar(0, 999999999, 'p_e_%d_%d_%d' % (i, j,e))
                itv2 = model.NewIntVar(-999999999, 999999999, 'itv2_%d_%d_%d' % (i, j, e))
                itv3 = model.NewIntVar(0, 999999999, 'itv3_%d_%d_%d' % (i, j, e))
                itv4 = model.NewIntVar(0, 999999999, 'itv4_%d_%d_%d' % (i, j, e))
                ems_itv = model.NewIntVar(0, 999999999, 'ems_itv_%d_%d_%d' % (i, j, e))
                for p in range(len(job_data[i][j][e])):  # 货物类型遍历
                    total_interval = 0  # 速度总和的变量
                    for k in range(len(total_C_list[i][j][e][p])):
                        total_interval += total_C_list[i][j][e][p][k] * V_j[job_type[i][j][e][p]]
                    t_i = model.NewIntVar(1, 99999999, 't_i_%d' % j)
                    model.Add(t_i == total_interval + 1)  # 速度计算，待处理
                    I = model.NewIntVar(0, 99999999, 'In_%d' % j)
                    model.AddDivisionEquality(I, job_data[i][j][e][p] * 10000, t_i)
                    ini.append(job_p_list[i][j][e][p][0])
                    cd.append(I)

                    kk = 0
                    if job_type[i][j][e][p] == 1:  # 件箱货物形态
                        for u in range(len(c[i][j][0])):
                            if c[i][j][0][u] == 1:  # 通道可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))
                                j_sub_c_intervals = model.NewOptionalIntervalVar(u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                rs_c.append(j_sub_p_intervals)
                                rs_ems_delivery_count.append(j_sub_p_intervals)
                                de.append(int(V_j[1]))
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                    else:
                        for u in range(len(c[i][j][1])):
                            if c[i][j][1][u] == 1:  # 通道可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))
                                j_sub_c_intervals = model.NewOptionalIntervalVar(p_num + u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                if len(ini) == 2:  # 若一辆车有两种类型的货物
                    model.Add(ini[0] == ini[1])  # 限制开始处理时间相同
                    model.Add(bool_sub_job_list[i][j][e][0] == bool_sub_job_list[i][j][e][1])
                    I_v = model.NewIntVar(0, 99999999, 'p_e_%d_%d' % (i, j))
                    model.AddMaxEquality(I_v, cd)
                    #
                    if len(interval_time) > 0:  #实现真实间隔约束
                        real_time_bool_var = 0
                        for kt in range(len(interval_time)):
                            it_bool_val = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            it_bool_val2 = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            rag11 = model.NewBoolVar('rag11_%d_%d%d%d' % (i, j, e, kt))
                            rag12 = model.NewBoolVar('rag12_%d_%d%d%d' % (i, j, e, kt))
                            rag13 = model.NewBoolVar('rag13_%d_%d%d%d' % (i, j, e, kt))
                            model.Add(ini[0] < work_time_list[kt][1]).OnlyEnforceIf(rag11)  #表示开始时间早于不连续区间的标志位
                            model.Add(ini[0] >= work_time_list[kt][1]).OnlyEnforceIf(rag11.Not())
                            model.Add(mm_v >= work_time_list[kt + 1][0]).OnlyEnforceIf(rag12)#表示结束时间晚于不连续区间的标志位
                            model.Add(mm_v < work_time_list[kt + 1][0]).OnlyEnforceIf(rag12.Not())
                            model.Add(ini[0] + I_v < work_time_list[kt][1]).OnlyEnforceIf(rag13) #表示开始时间加上时间间隔早于不连续区间的标志位
                            model.Add(ini[0] + I_v >= work_time_list[kt][1]).OnlyEnforceIf(rag13.Not())
                            model.AddMultiplicationEquality(it_bool_val, [rag11, rag12]) #表示开始时间早于不连续区间的同时结束时间晚于不连续区间的标志位
                            model.AddMultiplicationEquality(it_bool_val2, [it_bool_val, rag13])#表示开始时间早于不连续区间、结束时间晚于不连续区间、开始时间加上时间间隔早于不连续区间的标志位
                            real_time_bool_var += it_bool_val2 * interval_time[kt]

                        model.Add(itv2 == int(ems_interval_time[i]) - real_time_bool_var)  #若出跨时间间隔，则将这部分时间减去
                        model.AddMaxEquality(itv3, (0, itv2))                    #减完后的时间小于0则为0
                        model.Add(itv4 >= itv3)                                 #真实时间间隔
                        model.Add(itv4 <= int(ems_interval_time[i]))
                        model.Add(ems_itv == I_v + itv4 + 1)
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], ems_itv,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    else:
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                                                                           I_v + int(ems_interval_time[i]) + 1,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    # j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                    #                                                    I_v + int(ems_interval_time[i]) + 1,
                    #                                                    mm_v,
                    #                                                    bool_sub_job_list[i][j][e][0],
                    #                                                    '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)
                else:
                    if len(interval_time) > 0:  #实现真实间隔约束
                        real_time_bool_var = 0
                        for kt in range(len(interval_time)):
                            it_bool_val = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            it_bool_val2 = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            rag11 = model.NewBoolVar('rag11_%d_%d%d%d' % (i, j, e, kt))
                            rag12 = model.NewBoolVar('rag12_%d_%d%d%d' % (i, j, e, kt))
                            rag13 = model.NewBoolVar('rag13_%d_%d%d%d' % (i, j, e, kt))
                            model.Add(ini[0] < work_time_list[kt][1]).OnlyEnforceIf(rag11)  #表示开始时间早于不连续区间的标志位
                            model.Add(ini[0] >= work_time_list[kt][1]).OnlyEnforceIf(rag11.Not())
                            model.Add(mm_v >= work_time_list[kt][1]).OnlyEnforceIf(rag12)#表示结束时间晚于不连续区间的标志位
                            model.Add(mm_v < work_time_list[kt][1]).OnlyEnforceIf(rag12.Not())
                            model.Add(ini[0] +cd[0] < work_time_list[kt][1]).OnlyEnforceIf(rag13) #表示开始时间加上时间间隔早于不连续区间的标志位
                            model.Add(ini[0] +cd[0]>= work_time_list[kt][1]).OnlyEnforceIf(rag13.Not())
                            model.AddMultiplicationEquality(it_bool_val, [rag11, rag12])#表示开始时间早于不连续区间的同时结束时间晚于不连续区间的标志位
                            model.AddMultiplicationEquality(it_bool_val2, [it_bool_val, rag13])#表示开始时间早于不连续区间、结束时间晚于不连续区间、开始时间加上时间间隔早于不连续区间的标志位
                            real_time_bool_var += it_bool_val2 * interval_time[kt]

                        model.Add(itv2 == int(ems_interval_time[i]) - real_time_bool_var)#若出跨时间间隔，则将这部分时间减去
                        model.AddMaxEquality(itv3, (0, itv2))#减完后的时间小于0则为0
                        model.Add(itv4 >= itv3)   #真实时间间隔
                        model.Add(itv4 <= int(ems_interval_time[i]))
                        model.Add(ems_itv == cd[0] + itv4 + 1)
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], ems_itv,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    else:
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                                                                           cd[0] + int(ems_interval_time[i]) + 1,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    # j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                    #                                                    cd[0] + int(ems_interval_time[i]) + 1,
                    #                                                    mm_v,
                    #                                                    bool_sub_job_list[i][j][e][0],
                    #                                                    '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)
                    x_tt_ems_itv.append(ems_itv)
                    x_tt_ini.append(ini[0])
                    x_tt_mmv.append(mm_v)
                    x_tt_itv2.append(itv2)
                    x_tt_itv3.append(itv3)
                    x_tt_cd.append(cd[0])
            model.AddNoOverlap(x_tt_intervals)

    load_rate = []

    for i in range(len(job_data)): #计算装载率
        sub_load_rate = []
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                total_goods = 0
                for p in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][p] == 0:
                        total_goods += job_data[i][j][k][p] * zhuan_hua_EMS[i]
                    else:
                        total_goods += job_data[i][j][k][p]
                sub_load_rate.append(total_goods / rong_liang_EMS[i])
        load_rate.append(sub_load_rate)

    load_rate_index = []

    for i in range(len(load_rate)):
        sub_load_rate = sorted(enumerate(load_rate[i]), key=lambda x: x[1], reverse=True)
        sub_load_index = [ind for ind, _ in sub_load_rate]
        load_rate_index.append(sub_load_index)

    for i in range(len(load_rate_index)):  # 装载率高的优先排前面
        if len(load_rate_index[i]) > 1:
            for k in range(len(load_rate_index[i]) - 1):
                model.Add(
                    job_p_list[i][0][load_rate_index[i][k]][0][0] < job_p_list[i][0][load_rate_index[i][k + 1]][0][0])

    # for i in range(len(job_p_list)):
    #     for j in range(len(job_p_list[i])):
    #         if len(job_p_list[i][j]) > 1:
    #             for k in range(len(job_p_list[i][j]) - 1):
    #                 model.Add(job_p_list[i][j][k][0][0] < job_p_list[i][j][k + 1][0][0])
    de_zz_delivery_count = [1] * len(rs_zz_delivery_count)
    de_ems_delivery_count = [1] * len(rs_ems_delivery_count)

    model.AddNoOverlap2D(x_intervals, y_intervals)
    model.AddCumulative(rs_c, de, int(10000 * dis * box_flow_value))  # 件箱库流量约束
    model.AddCumulative(rs_zz_delivery_count, de_zz_delivery_count, zz_delivery_count) #最大自制通道约自制
    model.AddCumulative(rs_ems_delivery_count, de_ems_delivery_count, ems_delivery_count)   #最大ems通道约束



    # # 优先级逻辑，待处理
    # for i in range(len(job_data) - 1):
    #     model.Add(bool_job_list[i] == 1).OnlyEnforceIf(bool_job_list[i + 1])

    # 优先级逻辑
    # car_first_start_time = []
    #
    # for i in range(len(job_p_list)):
    #     sub_car_first_start_time = []
    #     for j in range(len(job_p_list[i])):
    #         for k in range(len(job_p_list[i][j])):
    #             sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
    #     car_first_start_time.append(sub_car_first_start_time)
    #
    # for i in range(len(car_first_start_time) - 1):
    #     first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % i)
    #     next_first_start_time = model.NewIntVar(0, 99999, 'first_start_time_%d' % (i + 1))
    #     model.AddMinEquality(first_start_time, car_first_start_time[i])
    #     model.AddMinEquality(next_first_start_time, car_first_start_time[i + 1])
    #     model.Add(first_start_time <= next_first_start_time)
    priority_index = sorted(ems_priority)
    car_first_start_time = []
    for i in range(len(job_p_list)):
        sub_car_first_start_time = []
        for j in range(len(job_p_list[i])):
            for k in range(len(job_p_list[i][j])):
                sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
        car_first_start_time.append(sub_car_first_start_time)

    left = 0
    for i in range(1, len(car_first_start_time)):
        if (priority_index[i] > priority_index[i - 1]):
            for j in range(left, i):
                first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % i)
                next_first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % (i + 1))
                model.AddMinEquality(first_start_time, car_first_start_time[j])
                model.AddMinEquality(next_first_start_time, car_first_start_time[i])
                model.Add(first_start_time <= next_first_start_time)
            left = i
    model.Maximize(total_bbb)  # 最大化排进去的车
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8
    solver.parameters.max_time_in_seconds = t
    solver.parameters.random_seed = 0
    status1 = solver.Solve(model)

    # 得到最终的解
    solution_find = False

    if status1 == cp_model.OPTIMAL or status1 == cp_model.FEASIBLE:
        model.Add(total_bbb == round(solver.ObjectiveValue()))
        model.Minimize(sum(min_end_time))
        status2 = solver.Solve(model)
        if status2 == cp_model.OPTIMAL or status2 == cp_model.FEASIBLE:
            solution_find = True
            if status1 == cp_model.OPTIMAL and status2 == cp_model.OPTIMAL:
                logger.info("EMS时间窗模型求得最优解")
            elif (status1 == cp_model.FEASIBLE or status1 == cp_model.OPTIMAL) and (status2 == cp_model.FEASIBLE or status2 == cp_model.OPTIMAL):
                logger.info("EMS时间窗模型求得次优解")
            else:
                logger.info("EMS时间窗模型无解,程序结束")
                # exit()
    if solution_find == False:
        logger.error("EMS时间窗模型无解,程序结束")
        # exit()

    for i in range(len(job_data)):
        solu_x_sub = []
        for j in range(len(job_data[i])):
            u_solu_x_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    solution_x = []
                    if not solution_find:
                        solution_x.append(0)
                        solution_x.append(0)
                    else:
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][0]))
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][1]))
                    so.append(solution_x)
                u_solu_x_sub.append(so)
            solu_x_sub.append(u_solu_x_sub)
        solution_x_total.append(solu_x_sub)

    for i in range(len(job_data)):
        solu_bool_sub = []
        for j in range(len(job_data[i])):
            u_solu_bool_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    if not solution_find:
                        so.append(0)
                    else:
                        so.append(solver.Value(bool_sub_job_list[i][j][g][k]))
                u_solu_bool_sub.append(so)
            solu_bool_sub.append(u_solu_bool_sub)
        solution_bool_sub_job.append(solu_bool_sub)

    for i in range(len(job_data)):
        solu_C_sub = []
        for j in range(len(job_data[i])):
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])):
                u_solu_C_sub_sub = []
                if len(job_data[i][j][e]) == 2:
                    so = []
                    c_index_list = []
                    for p in range(len(job_data[i][j][e])):
                        if job_type[i][j][e][p] == 1:
                            c_index_list.append(p)

                    for p in range(len(job_data[i][j][e])):
                        if job_type[i][j][e][p] == 0:
                            c_index_list.append(p)

                    for w in range(len(total_C_list[i][j][e][c_index_list[0]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[0]][w]))

                    so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])


                    for w in range(len(total_C_list[i][j][e][c_index_list[1]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[1]][w]))

                    u_solu_C_sub_sub.append(so)

                else:
                    so = []
                    if job_type[i][j][e][0] == 1:
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))

                        so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])

                        so = so + [0] * len(c[0][0][1])
                        u_solu_C_sub_sub.append(so)
                    else:
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        so = [0] * len(c[0][0][0]) + so
                        u_solu_C_sub_sub.append(so)

                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C.append(solu_C_sub)

    return solution_x_total, solution_bool_sub_job, solution_bool_C


def time_window_process_se(t, zz_begin_time, zz_end_time):
    '''
    时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    这个函数处理了自制发车表的开始时间和结束时间
    :param t: 时间窗
    :param zz_begin_time: 自制发车表的开始时间
    :param zz_end_time: 自制发车表的结束时间
    :return: zz_begin_time 处理好的自制发车表的开始时间, zz_end_time 处理好的自制发车表的结束时间
    '''

    n_t = []
    check_work = []

    if len(t) > 1:
        for i in range(len(t)):
            if i != 0:
                if t[i][0] - t[i - 1][1] > 0:
                    n_t.append([t[i - 1][1], t[i][0]])
                    n_t.append([t[i][0], t[i][1]])
                    check_work.append(0)
                    check_work.append(1)
                else:
                    n_t.append([t[i][0], t[i][1]])
                    check_work.append(1)
            else:
                n_t.append([t[i][0], t[i][1]])
                check_work.append(1)
    else:
        n_t.append([t[0][0], t[0][1]])
        check_work.append(1)

    for i in range(len(zz_begin_time)):
        for j in range(len(zz_begin_time[i])):
            no_work_time = 0
            for k in range(len(n_t)):
                if zz_begin_time[i][j] >= n_t[k][0] and zz_begin_time[i][j] <= n_t[k][1]:
                    if check_work[k] == 1:
                        zz_begin_time[i][j] = math.floor(zz_begin_time[i][j] - no_work_time)
                        break
                    else:
                        zz_begin_time[i][j] = math.floor(
                            zz_begin_time[i][j] - no_work_time - (zz_begin_time[i][j] - n_t[k][0]))
                        break
                else:
                    if check_work[k] == 0:
                        no_work_time += n_t[k][1] - n_t[k][0]

    for i in range(len(zz_end_time)):
        for j in range(len(zz_end_time[i])):
            no_work_time = 0
            for k in range(len(n_t)):
                if zz_end_time[i][j] >= n_t[k][0] and zz_end_time[i][j] <= n_t[k][1]:
                    if check_work[k] == 1:
                        zz_end_time[i][j] = math.ceil(zz_end_time[i][j] - no_work_time)
                        break
                    else:
                        zz_end_time[i][j] = math.ceil(
                            zz_end_time[i][j] - no_work_time - (zz_end_time[i][j] - n_t[k][0]))
                        break
                else:
                    if check_work[k] == 0:
                        no_work_time += n_t[k][1] - n_t[k][0]

    return zz_begin_time, zz_end_time


def time_window_process(t, start_time, d_list):
    '''
    时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    这个函数处理了EMS的开始时间和结束时间
    :param t: 时间窗
    :param start_time: 需要处理的开始时间
    :param d_list: 需要处理的结束时间
    :return: n_start_time 处理好的开始时间, n_d_list 处理好的结束时间, no_work_time_re 辅助参数方便后续使用, work_time_list 辅助参数方便后续使用
    '''
    interval_time = []
    for i in range(len(t)-1):
        interval_time.append(t[i+1][0] - t[i][1])

    tt = 0
    work_time_list = []
    no_work_time_re = []
    total_work_time = []
    n_t = []
    check_work = []
    n_start_time = []
    n_d_list = []

    for i in range(len(t)):
        if i == 0:
            total_work_time.append(t[0][0])
            tt += t[0][1]
        else:
            tt += t[i][1] - t[i][0]

    total_work_time.append(tt)

    if len(t) > 1:
        for i in range(len(t)):
            if i != 0:
                if t[i][0] - t[i - 1][1] > 0:
                    n_t.append([t[i - 1][1], t[i][0]])
                    n_t.append([t[i][0], t[i][1]])
                    check_work.append(0)
                    check_work.append(1)
                else:
                    n_t.append([t[i][0], t[i][1]])
                    check_work.append(1)
            else:
                n_t.append([t[i][0], t[i][1]])
                check_work.append(1)
    else:
        n_t.append([t[0][0], t[0][1]])
        check_work.append(1)

    for i in range(len(start_time)):
        no_work_time = 0
        for j in range(len(n_t)):
            if start_time[i] >= n_t[j][0] and start_time[i] <= n_t[j][1]:
                if check_work[j] == 1:
                    start_time[i] = math.floor(start_time[i] - no_work_time)
                    n_start_time.append(start_time[i])
                    break
                else:
                    start_time[i] = math.floor(start_time[i] - no_work_time - (start_time[i] - n_t[j][0]))
                    n_start_time.append(start_time[i])
                    break
            else:
                if check_work[j] == 0:
                    no_work_time += n_t[j][1] - n_t[j][0]

    for i in range(len(d_list)):
        no_work_time = 0
        for j in range(len(n_t)):
            if d_list[i] >= n_t[j][0] and d_list[i] <= n_t[j][1]:
                if check_work[j] == 1:
                    d_list[i] = d_list[i] - no_work_time
                    d_list[i] = math.ceil(d_list[i])
                    n_d_list.append(d_list[i])
                    break
                else:
                    d_list[i] = d_list[i] - no_work_time - (d_list[i] - n_t[j][0])
                    d_list[i] = math.ceil(d_list[i])
                    n_d_list.append(d_list[i])
                    break
            else:
                if check_work[j] == 0:
                    no_work_time += n_t[j][1] - n_t[j][0]

    no_work_time_1 = 0
    for i in range(len(check_work)):
        if check_work[i] == 1:
            no_work_time_re.append(no_work_time_1)
        else:
            no_work_time_1 += n_t[i][1] - n_t[i][0]

    ttt = 0

    if len(t) > 1:
        for i in range(len(t)):
            if i != 0:
                if t[i][0] - t[i - 1][1] > 0:
                    ttt += t[i][0] - t[i - 1][1]
                    work_time_list.append([t[i][0] - ttt, t[i][1] - ttt])
                else:
                    work_time_list.append([t[i][0] - ttt, t[i][1] - ttt])
            else:
                work_time_list.append([t[i][0], t[i][1]])
    else:
        work_time_list.append([t[0][0], t[0][1]])

    return n_start_time, n_d_list, no_work_time_re, work_time_list,interval_time


def get_end_time(solution_x_total, solution_bool_sub_job, no_work_time_re, work_time_list):
    '''
    该函数用于得到加入不工作时间后最终的时间窗结果
    :param solution_x_total: 所有子任务的开始处理时间和处理结束时间，单位为分钟
    :param solution_bool_sub_job: 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    :param no_work_time_re: 辅助处理的参数
    :param work_time_list: 辅助处理的参数
    :return: solution_x_total：最终所有子任务的开始处理时间和处理结束时间，单位为分钟
    '''
    # 720 1020
    for i in range(len(solution_x_total)):
        for j in range(len(solution_x_total[i])):
            for k in range(len(solution_x_total[i][j])):
                for p in range(len(solution_x_total[i][j][k])):
                    if solution_bool_sub_job[i][j][k][p] == 1:

                        for n in range(len(work_time_list)):
                            if solution_x_total[i][j][k][p][0] >= work_time_list[n][0] and solution_x_total[i][j][k][p][
                                0] < work_time_list[n][1]:
                                solution_x_total[i][j][k][p][0] += no_work_time_re[n]
                                break

                        for m in range(len(work_time_list)):
                            if solution_x_total[i][j][k][p][1] > work_time_list[m][0] and solution_x_total[i][j][k][p][
                                1] <= work_time_list[m][1]:
                                solution_x_total[i][j][k][p][1] += no_work_time_re[m]
                                break

    return solution_x_total


def get_end_zz_time(car_time_before, end_sxt, sbsj):
    '''
    该函数用于将自制的真实工作时间转换为自制的发车表时间
    :param car_time_before: 之前自制的车分配的时间
    :param end_sxt: 自制的真实作业时间
    :param sbsj: 货物是否被排入
    :return: end_sxt：处理后的时间，真实时间转变为发车表时间
    '''
    for i in range(len(sbsj)):
        for j in range(len(sbsj[i])):
            for k in range(len(sbsj[i][j])):
                for p in range(len(sbsj[i][j][k])):
                    if sbsj[i][j][k][p] == 1:
                        end_sxt[i][j][k][p][0] = car_time_before[i][j][k][0]
                        end_sxt[i][j][k][p][1] = car_time_before[i][j][k][1]

    return end_sxt


def time_sort(zz_begin_time_i, zz_end_time_i, zz_car_num_i):
    # 该函数用于对自制的发车表进行排序
    zz_begin_time_1 = []
    zz_end_time_1 = []
    zz_car_num_1 = []
    total_list = []

    for (i, j, k) in zip(zz_begin_time_i, zz_end_time_i, zz_car_num_i):
        total_sub_list = []
        total_sub_list.append(i)
        total_sub_list.append(j)
        total_sub_list.append(k)
        total_list.append(total_sub_list)

    total_list = sorted(total_list, key=lambda x: x[0])

    for m in range(len(total_list)):
        zz_begin_time_1.append(total_list[m][0])
        zz_end_time_1.append(total_list[m][1])
        zz_car_num_1.append(total_list[m][2])

    return zz_begin_time_1, zz_end_time_1, zz_car_num_1


def get_ini_zz_time_car(zz_begin_time, zz_end_time, zz_car_num):
    '''
    自制的发车表时间是乱的，需要进行一个初步处理，让发车表时间从小到大排序，发车表的车辆也依次对应起来
    :param zz_begin_time: 自制发车表的开始时间
    :param zz_end_time: 自制发车表的结束时间
    :param zz_car_num: 自制发车表对应的车辆
    :return:
    '''
    e_zz_begin_time = []
    e_zz_end_time = []
    e_zz_car_num = []

    for i in range(len(zz_begin_time)):  # 按照厂家依次处理
        a_1, b_1, c_1 = time_sort(zz_begin_time[i], zz_end_time[i], zz_car_num[i])
        e_zz_begin_time.append(a_1)
        e_zz_end_time.append(b_1)
        e_zz_car_num.append(c_1)

    return e_zz_begin_time, e_zz_end_time, e_zz_car_num


def process_job_re(job_re):
    '''
    处理合并后的下标，即将重复的下标去掉
    :param job_re: EMS和自制合并后的下标
    :return: job_re_end: 处理完后的下标
    '''

    job_re_end = []

    for i in range(len(job_re)):
        re_sub = []
        for j in range(len(job_re[i])):
            re_sub_sub = []
            for k in range(len(job_re[i][j])):
                unique_items = set()
                car_re = []

                for item in job_re[i][j][k]:
                    item_tuple = tuple(item)
                    if item_tuple not in unique_items:
                        car_re.append(list(item_tuple))
                        unique_items.add(item_tuple)

                re_sub_sub.append(car_re)
            re_sub.append(re_sub_sub)
        job_re_end.append(re_sub)

    return job_re_end


def d_process(job_re_1, job_re_end_1, ems_car_d_num_1, ems_car_d_type_1, ems_car_d_goods_num_1, zz_car_d_num_1,
              zz_car_d_type_1, zz_car_d_goods_num_1):
    '''
    该函数用于得到客户需要的输出格式
    :param job_re_1: 合并后还未经处理的下标
    :param job_re_end_1: 合并后经过处理的下标
    :param ems_car_d_num_1: EMS装车模型货物的数据
    :param ems_car_d_type_1: EMS装车模型货物对应的类型的数据
    :param ems_car_d_goods_num_1: EMS装车模型货物内部数量的数据
    :param zz_car_d_num_1: 自制装车模型货物的数据
    :param zz_car_d_type_1: 自制装车模型货物对应的类型的数据
    :param zz_car_d_goods_num_1: 自制装车模型货物内部数量的数据
    :return: total_d_num:客户需要的输出格式，对应货物的数量, total_d_goods:客户需要的输出格式，对应货物内部的数量
    '''
    in_total_car_num = ems_car_d_num_1 + zz_car_d_num_1
    in_total_car_goods_num = ems_car_d_goods_num_1 + zz_car_d_goods_num_1
    in_total_car_type = ems_car_d_type_1 + zz_car_d_type_1

    total_d_num = []
    total_d_goods = []

    for i in range(len(job_re_end_1)):
        sub_total_d_num = []
        sub_total_d_goods = []
        for j in range(len(job_re_end_1[i])):
            sub_sub_total_d_num = []
            sub_sub_total_d_goods = []
            for k in range(len(job_re_end_1[i][j])):
                sub_sub_sub_total_d_num = []
                sub_sub_sub_total_d_goods = []
                for p in range(len(job_re_end_1[i][j][k])):
                    sub_sub_sub_total_d_num.append([0, 0])
                    sub_sub_sub_total_d_goods.append([0, 0])
                sub_sub_total_d_num.append(sub_sub_sub_total_d_goods)
                sub_sub_total_d_goods.append(sub_sub_sub_total_d_num)
            sub_total_d_num.append(sub_sub_total_d_num)
            sub_total_d_goods.append(sub_sub_total_d_goods)
        total_d_num.append(sub_total_d_num)
        total_d_goods.append(sub_total_d_goods)

    for i in range(len(job_re_1)):
        for j in range(len(job_re_1[i])):
            for k in range(len(job_re_1[i][j])):
                for p in range(len(job_re_1[i][j][k])):
                    if in_total_car_type[i][j][k][p] == 1:
                        total_d_num[i][j][k][job_re_end_1[i][j][k].index(job_re_1[i][j][k][p])][0] = \
                            in_total_car_num[i][j][k][p]
                        total_d_goods[i][j][k][job_re_end_1[i][j][k].index(job_re_1[i][j][k][p])][0] = \
                            in_total_car_goods_num[i][j][k][p]
                    else:
                        total_d_num[i][j][k][job_re_end_1[i][j][k].index(job_re_1[i][j][k][p])][1] = \
                            in_total_car_num[i][j][k][p]
                        total_d_goods[i][j][k][job_re_end_1[i][j][k].index(job_re_1[i][j][k][p])][1] = \
                            in_total_car_goods_num[i][j][k][p]

    return total_d_num, total_d_goods


def start_end_time_process(ems_begin_time, ems_end_time, time_windows,logger):
    '''
    由于EMS给出的开始时间和deadline可能不在时间窗的范围内，因此这里做出处理，若不在范围内，就以时间窗的最早开始时间和最晚结束时间作为EMS厂家的开始时间和deadline
    :param ems_begin_time:EMS的开始时间
    :param ems_end_time:EMS的结束时间
    :param time_windows:时间窗
    :return:ems_begin_time EMS的开始时间, ems_end_time EMS的结束时间·
    '''

    min_time = time_windows[0][0]
    max_time = time_windows[-1][-1]

    for i in range(len(ems_begin_time)):
        if ems_begin_time[i] < min_time:
            ems_begin_time[i] = min_time

    for j in range(len(ems_end_time)):
        if ems_end_time[j] > max_time:
            ems_end_time[j] = max_time

    for i in range(len(ems_begin_time)):
        if ems_begin_time[i] > ems_end_time[i]:
            logger.error("ems的开始时间晚于结束时间,排不进货物！程序结束")
            exit()

    return ems_begin_time, ems_end_time


def solution_c_ems_process(end_solution_x_total, ems_goods_num, ems_job_type, solution_bool_sub_job, solution_bool_C,
                           job_re, v_ems_j, dis, c, v_se_j):
    '''
    该函数对资源占用过多的通道进行处理
    :param end_solution_x_total: 时间窗得到的求解时间
    :param ems_goods_num: 货物内部数量
    :param ems_job_type: 货物对应的类型
    :param solution_bool_sub_job: 排入的货物是否有效
    :param solution_bool_C: 通道占用情况
    :param job_re: 货物的下标
    :param v_j: 速度情况
    :param dis: 打折系数
    :return: solution_bool_C：处理完成的通道
    '''

    # for v in range(len(v_j)):
    #     if int(v_j[v] * dis) != 0:
    #         v_j[v] = int(v_j[v] * dis)
    #     else:
    #         v_j[v] = 1

    for v in range(len(v_ems_j)):
        v_ems_j[v] = v_ems_j[v] * dis

    for v in range(len(v_se_j)):
        v_se_j[v] = v_se_j[v] * dis

    for i in range(len(solution_bool_sub_job)):
        for j in range(len(solution_bool_sub_job[i])):
            for k in range(len(solution_bool_sub_job[i][j])):
                for p in range(len(solution_bool_sub_job[i][j][k])):
                    if solution_bool_sub_job[i][j][k][p] == 1:
                        if sum(solution_bool_C[i][j][k][0]) > 1:
                            # for b in range(len(job_re[i][j][k])):
                            #     for q in range(len(ems_job_type[i][j][job_re[i][j][k][b][2]])):
                            if ems_job_type[i][j][k][p] == 1 and sum(
                                    solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) > 1:
                                if ems_goods_num[i][j][k][p] <= (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        v_ems_j[1] + 0.01):
                                    c_list = []
                                    for n in range(len(solution_bool_C[i][j][k][0])):
                                        if n < len(c[0][0][0]):
                                            if solution_bool_C[i][j][k][0][n] == 1:
                                                c_list.append(n)
                                    z_list = random.sample(c_list,
                                                           sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - 1)
                                    for m in range(len(z_list)):
                                        solution_bool_C[i][j][k][0][z_list[m]] = 0
                                elif ems_goods_num[i][j][k][p] < (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        (sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - 1) * v_ems_j[
                                    1] + 0.01) and ems_goods_num[i][j][k][p] > (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        v_ems_j[1] + 0.01):
                                    c_num = (ems_goods_num[i][j][k][p] / (
                                            end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][
                                        0]) - 0.01) / v_ems_j[1]
                                    c_num = int(c_num) + (c_num % 1 > 0)
                                    c_list = []
                                    for n in range(len(solution_bool_C[i][j][k][0])):
                                        if n < len(c[0][0][0]):
                                            if solution_bool_C[i][j][k][0][n] == 1:
                                                c_list.append(n)
                                    z_list = random.sample(c_list,
                                                           sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - c_num)
                                    for m in range(len(z_list)):
                                        solution_bool_C[i][j][k][0][z_list[m]] = 0
                            if ems_job_type[i][j][k][p] == 0 and sum(
                                    solution_bool_C[i][j][k][0][len(c[0][0][0])::]) > 1:
                                if ems_goods_num[i][j][k][p] <= (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        v_ems_j[0] + 0.01):
                                    c_list = []
                                    for n in range(len(solution_bool_C[i][j][k][0])):
                                        if n >= len(c[0][0][0]):
                                            if solution_bool_C[i][j][k][0][n] == 1:
                                                c_list.append(n)
                                    z_list = random.sample(c_list,
                                                           sum(solution_bool_C[i][j][k][0][len(c[0][0][0])::]) - 1)
                                    for m in range(len(z_list)):
                                        solution_bool_C[i][j][k][0][z_list[m]] = 0
                                elif ems_goods_num[i][j][k][p] < (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        (sum(solution_bool_C[i][j][k][0][len(c[0][0][0])::]) - 1) * v_ems_j[
                                    0] + 0.01) and ems_goods_num[i][j][k][p] > (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                        v_ems_j[0] + 0.01):
                                    c_num = (ems_goods_num[i][j][k][p] / (
                                            end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][
                                        0]) - 0.01) / v_ems_j[0]
                                    c_num = int(c_num) + (c_num % 1 > 0)
                                    c_list = []
                                    for n in range(len(solution_bool_C[i][j][k][0])):
                                        if n >= len(c[0][0][0]):
                                            if solution_bool_C[i][j][k][0][n] == 1:
                                                c_list.append(n)
                                    z_list = random.sample(c_list,
                                                           sum(solution_bool_C[i][j][k][0][len(c[0][0][0])::]) - c_num)
                                    for m in range(len(z_list)):
                                        solution_bool_C[i][j][k][0][z_list[m]] = 0

    return solution_bool_C


def solution_c_zz_process(end_solution_x_total, ems_goods_num, ems_job_type, solution_bool_sub_job, solution_bool_C,
                          job_re, v_ems_j, dis, c, v_se_j):
    '''
    该函数对资源占用过多的通道进行处理
    :param end_solution_x_total: 时间窗得到的求解时间
    :param ems_goods_num: 货物内部数量
    :param ems_job_type: 货物对应的类型
    :param solution_bool_sub_job: 排入的货物是否有效
    :param solution_bool_C: 通道占用情况
    :param job_re: 货物的下标
    :param v_j: 速度情况
    :param dis: 打折系数
    :return: solution_bool_C：处理完成的通道
    '''

    # for v in range(len(v_j)):
    #     if int(v_j[v] * dis) != 0:
    #         v_j[v] = int(v_j[v] * dis)
    #     else:
    #         v_j[v] = 1

    for v in range(len(v_ems_j)):
        v_ems_j[v] = v_ems_j[v] * dis

    for v in range(len(v_se_j)):
        v_se_j[v] = v_se_j[v] * dis

    for i in range(len(solution_bool_sub_job)):
        for j in range(len(solution_bool_sub_job[i])):
            for k in range(len(solution_bool_sub_job[i][j])):
                for p in range(len(solution_bool_sub_job[i][j][k])):
                    if solution_bool_sub_job[i][j][k][p] == 1:
                        # if sum(solution_bool_C[i][j][k][0]) > 1:
                        # for b in range(len(job_re[i][j][k])):
                        #     for q in range(len(ems_job_type[i][j][job_re[i][j][k][b][2]])):
                        if ems_job_type[i][j][k][p] == 1 and len(solution_bool_C[i][j][k][0]) == (
                                len(c[0][0][0]) + len(c[0][0][1])) and sum(
                            solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) > 1:
                            if ems_goods_num[i][j][k][p] <= (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                    v_ems_j[1] + 0.01):
                                c_list = []
                                for n in range(len(solution_bool_C[i][j][k][0])):
                                    if n < len(c[0][0][0]):
                                        if solution_bool_C[i][j][k][0][n] == 1:
                                            c_list.append(n)
                                z_list = random.sample(c_list, sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - 1)
                                for m in range(len(z_list)):
                                    solution_bool_C[i][j][k][0][z_list[m]] = 0
                            elif ems_goods_num[i][j][k][p] < (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                    (sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - 1) * v_ems_j[1] + 0.01) and \
                                    ems_goods_num[i][j][k][p] > (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                    v_ems_j[1] + 0.01):
                                c_num = (ems_goods_num[i][j][k][p] / (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][
                                    0]) - 0.01) / v_ems_j[1]
                                c_num = int(c_num) + (c_num % 1 > 0)
                                c_list = []
                                for n in range(len(solution_bool_C[i][j][k][0])):
                                    if n < len(c[0][0][0]):
                                        if solution_bool_C[i][j][k][0][n] == 1:
                                            c_list.append(n)
                                z_list = random.sample(c_list,
                                                       sum(solution_bool_C[i][j][k][0][0:len(c[0][0][0])]) - c_num)
                                for m in range(len(z_list)):
                                    solution_bool_C[i][j][k][0][z_list[m]] = 0
                        if ems_job_type[i][j][k][p] == 0 and sum(solution_bool_C[i][j][k][0][-len(c[0][0][1])::]) > 1:
                            if ems_goods_num[i][j][k][p] <= (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                    v_ems_j[0] + 0.01):
                                c_list = []
                                for n in range(len(solution_bool_C[i][j][k][0])):
                                    if n >= (len(solution_bool_C[i][j][k][0]) - len(c[0][0][1])):
                                        if solution_bool_C[i][j][k][0][n] == 1:
                                            c_list.append(n)
                                z_list = random.sample(c_list, sum(solution_bool_C[i][j][k][0][(len(
                                    solution_bool_C[i][j][k][0]) - len(c[0][0][1]))::]) - 1)
                                for m in range(len(z_list)):
                                    solution_bool_C[i][j][k][0][z_list[m]] = 0
                            elif ems_goods_num[i][j][k][p] < (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * ((
                                                                                                                          sum(
                                                                                                                              solution_bool_C[
                                                                                                                                  i][
                                                                                                                                  j][
                                                                                                                                  k][
                                                                                                                                  0][
                                                                                                                              (
                                                                                                                                      len(
                                                                                                                                          solution_bool_C[
                                                                                                                                              i][
                                                                                                                                              j][
                                                                                                                                              k][
                                                                                                                                              0]) - len(
                                                                                                                                  c[
                                                                                                                                      0][
                                                                                                                                      0][
                                                                                                                                      1]))::]) - 1) *
                                                                                                                  v_ems_j[
                                                                                                                      0] + 0.01) and \
                                    ems_goods_num[i][j][k][p] > (
                                    end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][0]) * (
                                    v_ems_j[0] + 0.01):
                                c_num = (ems_goods_num[i][j][k][p] / (
                                        end_solution_x_total[i][j][k][p][1] - end_solution_x_total[i][j][k][p][
                                    0]) - 0.01) / v_ems_j[0]
                                c_num = int(c_num) + (c_num % 1 > 0)
                                c_list = []
                                for n in range(len(solution_bool_C[i][j][k][0])):
                                    if n >= (len(solution_bool_C[i][j][k][0]) - len(c[0][0][1])):
                                        if solution_bool_C[i][j][k][0][n] == 1:
                                            c_list.append(n)
                                z_list = random.sample(c_list, sum(solution_bool_C[i][j][k][0][(len(
                                    solution_bool_C[i][j][k][0]) - len(c[0][0][1]))::]) - c_num)
                                for m in range(len(z_list)):
                                    solution_bool_C[i][j][k][0][z_list[m]] = 0

    return solution_bool_C


def priority_process(ems_priority, zz_priority, ems_goods_num, ems_begin_time, ems_end_time, ems_job_type, ems_goods,
                     zz_goods_num, zz_begin_time, zz_end_time, zz_job_type, zz_goods, s_c, fu_dong_EMS, fu_dong_zz,
                     rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS, zhuan_hua_zz, EMS_interval_time, zz_interval_time,
                     zz_car_num, V_j, V_se_j, box_flow_value,p_num,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2
                     ):
    '''
    把数据按照优先级重新排序
    '''
    sorted_result_ems = sorted(enumerate(ems_priority), key=lambda x: x[1])
    sorted_result_zz = sorted(enumerate(zz_priority), key=lambda x: x[1])

    original_indices_ems = [index for index, _ in sorted_result_ems]
    original_indices_zz = [index for index, _ in sorted_result_zz]

    new_ems_goods_num = []
    new_ems_begin_time = []
    new_ems_end_time = []
    new_ems_job_type = []
    new_c = []
    new_ems_goods = []
    new_zz_goods_num = []
    new_zz_begin_time = []
    new_zz_end_time = []
    new_zz_job_type = []
    new_zz_goods = []
    new_s_c = []
    new_fu_dong_EMS = []
    new_fu_dong_zz = []
    new_rong_liang_EMS = []
    new_rong_liang_zz = []
    new_zhuan_hua_EMS = []
    new_zhuan_hua_zz = []
    new_EMS_interval_time = []
    new_zz_interval_time = []
    new_zz_car_num = []

    for i in original_indices_ems:
        new_ems_goods_num.append(ems_goods_num[i])
        new_ems_begin_time.append(ems_begin_time[i])
        new_ems_end_time.append(ems_end_time[i])
        new_ems_job_type.append(ems_job_type[i])
        # new_c.append(c[i])
        new_ems_goods.append(ems_goods[i])
        new_fu_dong_EMS.append(fu_dong_EMS[i])
        new_rong_liang_EMS.append(rong_liang_EMS[i])
        new_zhuan_hua_EMS.append(zhuan_hua_EMS[i])
        new_EMS_interval_time.append(EMS_interval_time[i])

    for j in original_indices_zz:
        new_zz_goods_num.append(zz_goods_num[j])
        new_zz_begin_time.append(zz_begin_time[j])
        new_zz_end_time.append(zz_end_time[j])
        new_zz_job_type.append(zz_job_type[j])
        new_zz_goods.append(zz_goods[j])
        new_zz_car_num.append(zz_car_num[j])
        new_s_c.append(s_c[j])
        new_fu_dong_zz.append(fu_dong_zz[j])
        new_rong_liang_zz.append(rong_liang_zz[j])
        new_zhuan_hua_zz.append(zhuan_hua_zz[j])
        new_zz_interval_time.append(zz_interval_time[j])

    for i in range(len(new_zz_begin_time)):

        indexed_A = list(enumerate(new_zz_begin_time[i]))

        sorted_indexed_A = sorted(indexed_A, key=lambda x: x[1])
        sorted_indices = [idx for idx, _ in sorted_indexed_A]

        new_zz_begin_time[i] = [new_zz_begin_time[i][idx] for idx in sorted_indices]
        new_zz_end_time[i] = [new_zz_end_time[i][idx] for idx in sorted_indices]
        new_zz_car_num[i] = [new_zz_car_num[i][idx] for idx in sorted_indices]

    V_j[1] = min(box_flow_value, V_j[1])
    V_j[2] = min(box_flow_value, V_j[2])
    V_se_j[1] = min(box_flow_value, V_se_j[1])
    V_se_j[2] = min(box_flow_value, V_se_j[2])

    if p_num <=  len(ems_goods_num) :
        portEmsLpnNum3 = sys.maxsize
        portEmsLpnNum2 = sys.maxsize
    if(len(s_c)>0):
        max_zz_num = max(p_num,max([len(s_c_i[0][0])/2 for s_c_i in s_c ]))
        if max_zz_num <= len(zz_goods_num):
            portSelfLpnNum2 = sys.maxsize

    return new_ems_goods_num, new_ems_begin_time, new_ems_end_time, new_ems_job_type, new_ems_goods, new_zz_goods_num, \
           new_zz_begin_time, new_zz_end_time, new_zz_job_type, new_zz_goods, new_s_c, new_fu_dong_EMS, new_fu_dong_zz, \
           new_rong_liang_EMS, new_rong_liang_zz, new_zhuan_hua_EMS, new_zhuan_hua_zz, new_EMS_interval_time, new_zz_interval_time, \
           original_indices_ems, original_indices_zz, new_zz_car_num, V_j, V_se_j,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2


def sub_remove_du_two(deliver_plan_time, detail_port_num):
    # 两个时间元素的去重
    new_deliver_plan_time = []
    new_detail_port_num = []
    new_detail_id_arr = []
    du_list = []
    unique_items = set()
    for i in range(len(deliver_plan_time)):
        # sub_du_list = deliver_plan_time[i] + detail_port_num[i]
        sub_du_list = []
        sub_du_list.append(tuple([tuple(deliver_plan_time[i][0]), tuple(deliver_plan_time[i][1])]))
        sub_du_list.append(tuple(detail_port_num[i]))
        du_list.append(sub_du_list)

    for i in range(len(deliver_plan_time)):
        item_tuple = tuple(du_list[i])
        if item_tuple not in unique_items:
            unique_items.add(item_tuple)
            new_deliver_plan_time.append([list(item_tuple[0][0]), list(item_tuple[0][1])])
            new_detail_port_num.append(list(item_tuple[1]))
            # new_detail_id_arr.append(detail_id_arr[i])

    return new_deliver_plan_time, new_detail_port_num


def sub_remove_du_one(deliver_plan_time, detail_port_num):
    # 只有一个时间元素的去重
    new_deliver_plan_time = []
    new_detail_port_num = []
    new_detail_id_arr = []
    du_list = []
    unique_items = set()
    for i in range(len(deliver_plan_time)):
        # sub_du_list = deliver_plan_time[i] + detail_port_num[i]
        sub_du_list = []
        sub_du_list.append(tuple(deliver_plan_time[i][0]))
        sub_du_list.append(tuple(detail_port_num[i]))
        du_list.append(sub_du_list)

    for i in range(len(deliver_plan_time)):
        item_tuple = tuple(du_list[i])
        if item_tuple not in unique_items:
            unique_items.add(item_tuple)
            new_deliver_plan_time.append([list(item_tuple[0])])
            new_detail_port_num.append(list(item_tuple[1]))
            # new_detail_id_arr.append(detail_id_arr[i])

    return new_deliver_plan_time, new_detail_port_num


def remove_du(ems_time_lock, ems_port_lock):
    # 主去重函数
    ems_time_lock_two = []
    ems_port_lock_two = []
    ems_time_lock_one = []
    ems_port_lock_one = []
    new_ems_time_lock_one = []
    new_ems_port_lock_one = []

    for i in range(len(ems_time_lock)):
        if len(ems_time_lock[i]) == 2:
            ems_time_lock_two.append(ems_time_lock[i])
            ems_port_lock_two.append(ems_port_lock[i])
        else:
            ems_time_lock_one.append(ems_time_lock[i])
            ems_port_lock_one.append(ems_port_lock[i])

    if bool(ems_time_lock_two):
        ems_time_lock_two, ems_port_lock_two = sub_remove_du_two(ems_time_lock_two, ems_port_lock_two)

    if bool(ems_time_lock_one):
        ems_time_lock_one, ems_port_lock_one = sub_remove_du_one(ems_time_lock_one, ems_port_lock_one)

    if bool(ems_time_lock_two) and bool(ems_time_lock_one):

        index_list = []

        for i in range(len(ems_time_lock_one)):
            for j in range(len(ems_time_lock_two)):
                if ems_time_lock_one[i][0] == ems_time_lock_two[j][0][0] and ems_port_lock_one[i] == ems_port_lock_two[
                    j]:
                    index_list.append(i)

        for i in range(len(ems_time_lock_one)):
            if i not in index_list:
                new_ems_time_lock_one.append(ems_time_lock_one[i])
                new_ems_port_lock_one.append(ems_port_lock_one[i])

        end_ems_time_lock = ems_time_lock_two + new_ems_time_lock_one
        end_ems_port_lock = ems_port_lock_two + new_ems_port_lock_one
    else:
        end_ems_time_lock = ems_time_lock_two + ems_time_lock_one
        end_ems_port_lock = ems_port_lock_two + ems_port_lock_one

    return end_ems_time_lock, end_ems_port_lock


def zz_sub_remove_du_two(deliver_plan_time, detail_port_num, ems_port_lock_two_id):
    # 两个时间元素的去重
    new_deliver_plan_time = []
    new_detail_port_num = []
    new_detail_id_arr = []
    du_list = []
    unique_items = set()
    for i in range(len(deliver_plan_time)):
        # sub_du_list = deliver_plan_time[i] + detail_port_num[i]
        sub_du_list = []
        sub_du_list.append(tuple([tuple(deliver_plan_time[i][0]), tuple(deliver_plan_time[i][1])]))
        sub_du_list.append(tuple(detail_port_num[i]))
        du_list.append(sub_du_list)

    for i in range(len(deliver_plan_time)):
        item_tuple = tuple(du_list[i])
        if item_tuple not in unique_items:
            unique_items.add(item_tuple)
            new_deliver_plan_time.append([list(item_tuple[0][0]), list(item_tuple[0][1])])
            new_detail_port_num.append(list(item_tuple[1]))
            new_detail_id_arr.append(ems_port_lock_two_id[i])

    return new_deliver_plan_time, new_detail_port_num, new_detail_id_arr


def zz_sub_remove_du_one(deliver_plan_time, detail_port_num, ems_port_lock_one_id):
    # 只有一个时间元素的去重
    new_deliver_plan_time = []
    new_detail_port_num = []
    new_detail_id_arr = []
    du_list = []
    unique_items = set()
    for i in range(len(deliver_plan_time)):
        # sub_du_list = deliver_plan_time[i] + detail_port_num[i]
        sub_du_list = []
        sub_du_list.append(tuple(deliver_plan_time[i][0]))
        sub_du_list.append(tuple(detail_port_num[i]))
        du_list.append(sub_du_list)

    for i in range(len(deliver_plan_time)):
        item_tuple = tuple(du_list[i])
        if item_tuple not in unique_items:
            unique_items.add(item_tuple)
            new_deliver_plan_time.append([list(item_tuple[0])])
            new_detail_port_num.append(list(item_tuple[1]))
            new_detail_id_arr.append(ems_port_lock_one_id[i])

    return new_deliver_plan_time, new_detail_port_num, new_detail_id_arr


def zz_remove_du(ems_time_lock, ems_port_lock, detail_id_arr):
    # 主去重函数
    ems_time_lock_two = []
    ems_port_lock_two = []
    ems_port_lock_two_id = []
    ems_time_lock_one = []
    ems_port_lock_one = []
    ems_port_lock_one_id = []
    new_ems_time_lock_one = []
    new_ems_port_lock_one = []
    new_ems_port_lock_one_id = []

    for i in range(len(ems_time_lock)):
        if len(ems_time_lock[i]) == 2:
            ems_time_lock_two.append(ems_time_lock[i])
            ems_port_lock_two.append(ems_port_lock[i])
            ems_port_lock_two_id.append(detail_id_arr[i])
        else:
            ems_time_lock_one.append(ems_time_lock[i])
            ems_port_lock_one.append(ems_port_lock[i])
            ems_port_lock_one_id.append(detail_id_arr[i])

    if bool(ems_time_lock_two):
        ems_time_lock_two, ems_port_lock_two, ems_port_lock_two_id = zz_sub_remove_du_two(ems_time_lock_two,
                                                                                          ems_port_lock_two,
                                                                                          ems_port_lock_two_id)

    if bool(ems_time_lock_one):
        ems_time_lock_one, ems_port_lock_one, ems_port_lock_one_id = zz_sub_remove_du_one(ems_time_lock_one,
                                                                                          ems_port_lock_one,
                                                                                          ems_port_lock_one_id)

    if bool(ems_time_lock_two) and bool(ems_time_lock_one):

        index_list = []

        for i in range(len(ems_time_lock_one)):
            for j in range(len(ems_time_lock_two)):
                if ems_time_lock_one[i][0] == ems_time_lock_two[j][0][0] and ems_port_lock_one[i] == ems_port_lock_two[
                    j]:
                    index_list.append(i)

        for i in range(len(ems_time_lock_one)):
            if i not in index_list:
                new_ems_time_lock_one.append(ems_time_lock_one[i])
                new_ems_port_lock_one.append(ems_port_lock_one[i])
                new_ems_port_lock_one_id.append(ems_port_lock_one_id[i])

        end_ems_time_lock = ems_time_lock_two + new_ems_time_lock_one
        end_ems_port_lock = ems_port_lock_two + new_ems_port_lock_one
        end_ems_port_lock_id = ems_port_lock_two_id + new_ems_port_lock_one_id
    else:
        end_ems_time_lock = ems_time_lock_two + ems_time_lock_one
        end_ems_port_lock = ems_port_lock_two + ems_port_lock_one
        end_ems_port_lock_id = ems_port_lock_two_id + ems_port_lock_one_id

    return end_ems_time_lock, end_ems_port_lock, end_ems_port_lock_id


def remove_lock_time(deliver_plan_time, detail_port_num, detail_id_arr, insert_time, zz_begin_time, zz_end_time,
                     zz_car_num, c, s_c, v_j, v_se_j, zz_interval_time, zz_car_m, zz_car_m_type, dis):
    # 资源判定

    for v in range(len(v_j)):
        v_j[v] = round(v_j[v] * dis, 4)

    # 对速度进行折扣处理
    for v in range(len(v_se_j)):
        v_se_j[v] = round(v_se_j[v] * dis, 4)

    lock_zz_id = []
    lock_zz_time = []
    lock_zz_port = []

    for i in range(len(detail_id_arr)):
        if bool(detail_id_arr[i]):
            # for j in range(len(detail_id_arr[i])):
            if detail_id_arr[i][0] == 0:
                lock_zz_id.append(detail_id_arr[i][1][0])
                lock_zz_time.append(deliver_plan_time[i])
                lock_zz_port.append(detail_port_num[i])

    lock_zz_time, lock_zz_port, lock_zz_id = zz_remove_du(lock_zz_time, lock_zz_port, lock_zz_id)

    for index, iid in enumerate(lock_zz_id):
        for ti in lock_zz_time[index]:
            for i in range(len(zz_begin_time[iid])):
                if ti[0] >= zz_begin_time[iid][i] and ti[1] <= zz_end_time[iid][i]:
                    zz_car_num[iid][i] -= 1
                    break

    ems_time = []
    ems_port = []

    for i in range(len(deliver_plan_time)):
        if bool(detail_id_arr[i]):
            if detail_id_arr[i][1] == 0:
                ems_time.append(deliver_plan_time[i])
                ems_port.append(detail_port_num[i])

    ems_time, ems_port = remove_du(ems_time, ems_port)

    # sub_sub_resource = []
    # sub_resource = []
    # total_resource = []
    # for i in range(len(zz_begin_time)):
    #     sub_resource = []
    #     for j in range(len(zz_begin_time[i])):
    #         sub_sub_resource = []
    #         ems_b = sum(c[0][0][0]) * v_j[1] * (zz_end_time[i][j] - zz_begin_time[i][j])
    #         p = sum(c[0][0][1]) * v_j[0] * (zz_end_time[i][j] - zz_begin_time[i][j])
    #         zz_b = v_se_j[1] * (zz_end_time[i][j] - zz_begin_time[i][j])
    #         sub_sub_resource.append(ems_b)
    #         sub_sub_resource.append(p)
    #         sub_sub_resource.append(zz_b)
    #     sub_resource.append(sub_sub_resource)
    # total_resource.append(sub_resource)

    goods_resource = []
    max_end_time = 0
    zz_e_t = {}
    zz_e_t_port = {}
    for i in range(len(lock_zz_time)):
        if len(lock_zz_time[i]) == 2:
            max_end_time = max(lock_zz_time[i][0][1], lock_zz_time[i][1][1]) + zz_interval_time[lock_zz_id[i]]
        else:
            max_end_time = lock_zz_time[i][0][1] + zz_interval_time[lock_zz_id[i]]

        if insert_time > max_end_time:
            max_end_time = insert_time

        if lock_zz_id[i] not in zz_e_t:
            zz_e_t[lock_zz_id[i]] = max_end_time
        else:
            if zz_e_t[lock_zz_id[i]] < max_end_time:
                zz_e_t[lock_zz_id[i]] = max_end_time

    for i, t in zz_e_t.items():
        if t >= zz_end_time[i][0]:
            if len(zz_end_time[i]) > 1:
                del zz_begin_time[i][0]
                del zz_end_time[i][0]
                del zz_car_num[i][0]
        else:
            re_source_ems_b = (zz_end_time[i][0] - t) * sum(c[0][0][0]) * v_j[1]  # 件箱的通道
            re_source_p = (zz_end_time[i][0] - t) * sum(c[0][0][1]) * v_j[0]  # 栈板的通道
            re_source_zz_b = (zz_end_time[i][0] - t) * v_se_j[1]

            ems_b = 0
            p = 0

            for m in range(len(ems_time)):
                if len(ems_time[m]) == 2:
                    if ems_time[m][0][0] < t and ems_time[m][0][1] > t and ems_time[m][0][1] < zz_end_time[i][0]:
                        ems_b += (ems_time[m][0][1] - t) * sum(ems_port[m][0:len(c[0][0][0])]) * v_j[1]
                    elif ems_time[m][0][0] > t and ems_time[m][0][1] > zz_end_time[i][0] and ems_time[m][0][0] < \
                            zz_end_time[i][0]:
                        ems_b += (zz_end_time[i][0] - ems_time[m][0][0]) * sum(ems_port[m][0:len(c[0][0][0])]) * v_j[1]
                    elif ems_time[m][0][0] <= t and ems_time[m][0][1] >= zz_end_time[i][0]:
                        ems_b += (zz_end_time[i][0] - t) * sum(ems_port[m][0:len(c[0][0][0])]) * v_j[1]

                    if ems_time[m][1][0] < t and ems_time[m][1][1] > t and ems_time[m][1][1] < zz_end_time[i][0]:
                        p += (ems_time[m][1][1] - t) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]
                    elif ems_time[m][1][0] > t and ems_time[m][1][1] > zz_end_time[i][0] and ems_time[m][1][0] < \
                            zz_end_time[i][0]:
                        p += (zz_end_time[i][0] - ems_time[m][1][0]) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]
                    elif ems_time[m][1][0] <= t and ems_time[m][1][1] >= zz_end_time[i][0]:
                        p += (zz_end_time[i][0] - t) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]
                else:
                    if sum(ems_port[m][0:len(c[0][0][0])]) >= 1:
                        if ems_time[m][0][0] < t and ems_time[m][0][1] > t and ems_time[m][0][1] < zz_end_time[i][0]:
                            ems_b += (ems_time[m][0][1] - t) * sum(ems_port[m][0:len(c[0][0][0])]) * v_j[1]
                        elif ems_time[m][0][0] > t and ems_time[m][0][1] > zz_end_time[i][1] and ems_time[m][0][0] < \
                                zz_end_time[i][0]:
                            ems_b += (zz_end_time[i][0] - ems_time[m][0][0]) * sum(ems_port[m][0:len(c[0][0][0])]) * \
                                     v_j[1]
                        elif ems_time[m][0][0] <= t and ems_time[m][0][1] >= zz_end_time[i][0]:
                            ems_b += (zz_end_time[i][0] - t) * sum(ems_port[m][0:len(c[0][0][0])]) * v_j[1]
                    else:
                        if ems_time[m][0][0] < t and ems_time[m][0][1] > t and ems_time[m][0][1] < zz_end_time[i][0]:
                            p += (ems_time[m][0][1] - t) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]
                        elif ems_time[m][0][0] > t and ems_time[m][0][1] > zz_end_time[i][1] and ems_time[m][0][0] < \
                                zz_end_time[i][0]:
                            p += (zz_end_time[i][0] - ems_time[m][1][0]) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]
                        elif ems_time[m][0][0] <= t and ems_time[m][0][1] >= zz_end_time[i][0]:
                            p += (zz_end_time[i][0] - t) * sum(ems_port[m][len(c[0][0][0])::]) * v_j[0]

            car_ems_b = 0
            car_p = 0
            car_zz_b = 0

            if s_c[i][0][0] == 1:
                for k in range(len(zz_car_m[i][0][0])):
                    if zz_car_m_type[i][0][0][k] == 1:
                        car_zz_b += zz_car_m[i][0][0][k]
                    else:
                        car_p += zz_car_m[i][0][0][k]
            else:
                for k in range(len(zz_car_m[i][0][0])):
                    if zz_car_m_type[i][0][0][k] == 1:
                        car_ems_b += zz_car_m[i][0][0][k]
                    else:
                        car_p += zz_car_m[i][0][0][k]

            if (re_source_ems_b - car_ems_b - ems_b) * (re_source_p - car_p - p) * (re_source_zz_b - car_zz_b) < 0:
                if len(zz_begin_time[i]) > 1:
                    del zz_begin_time[i][0]
                    del zz_end_time[i][0]
                    del zz_car_num[i][0]

    for i in range(len(zz_car_num)):
        for j in range(len(zz_car_num[i])):
            if zz_car_num[i][j] < 1:
                del zz_begin_time[i][j]
                del zz_end_time[i][j]
                del zz_car_num[i][j]
                break

    return zz_begin_time, zz_end_time, zz_car_num


def zz_process_1(job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, car_num, begin_time,
                 end_time):
    # 处理自制缺车的数据
    no_car_re_temp = []
    no_car_type_temp = []
    no_out_car_temp = []

    for i in range(len(job_total)):
        if bool(car_num[i]):
            total_car_num = sum(car_num[i])
            car_num_check = 0
            for j in range(len(job_total[i])):
                for k in range(len(job_total[i][j])):
                    if car_num_check < total_car_num:
                        car_num_check += 1
                    else:
                        no_car_re_temp += job_re[i][j][k:len(job_re[i][j])]
                        no_out_car_temp += out_car[i][j][k:len(out_car[i][j])]
                        no_car_type_temp += car_type[i][j][k:len(car_type[i][j])]
                        del job_total[i][j][k:len(job_total[i][j])]
                        del job_type_total[i][j][k:len(job_type_total[i][j])]
                        del job_re[i][j][k:len(job_re[i][j])]
                        del goods_num_new[i][j][k:len(goods_num_new[i][j])]
                        del out_car[i][j][k:len(out_car[i][j])]
                        del car_type[i][j][k:len(car_type[i][j])]
                        del car_goods_d[i][j][k:len(car_goods_d[i][j])]
                        break
        else:
            no_car_re_temp += job_re[i][0][:]
            no_out_car_temp += out_car[i][0][:]
            no_car_type_temp += car_type[i][0][:]

    job_total = [job_total[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    job_type_total = [job_type_total[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    job_re = [job_re[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    goods_num_new = [goods_num_new[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    out_car = [out_car[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    car_type = [car_type[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    car_goods_d = [car_goods_d[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    begin_time = [begin_time[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    end_time = [end_time[i] for i in range(len(car_num)) if bool(car_num[i]) is True]
    car_num = [car_num[i] for i in range(len(car_num)) if bool(car_num[i]) is True]



    no_car_re_temp = sum(no_car_re_temp, [])
    no_car_type_temp = sum(no_car_type_temp, [])
    no_out_car_temp = sum(no_out_car_temp, [])

    no_job_data_re_temp = [[no_car_type_temp[i] * no_out_car_temp[i], (1 - no_car_type_temp[i]) * no_out_car_temp[i]]
                           for i in range(len(no_car_re_temp))]

    new_no_job_data_re_temp = []
    new_no_car_re_temp = []
    re_s = set()
    for i in range(len(no_car_re_temp)):
        if tuple(no_car_re_temp[i]) not in re_s:
            re_s.add(tuple(no_car_re_temp[i]))
            new_no_car_re_temp.append(copy.deepcopy(no_car_re_temp[i]))
            new_no_job_data_re_temp.append(copy.deepcopy(no_job_data_re_temp[i]))
        else:
            new_no_job_data_re_temp[new_no_car_re_temp.index(no_car_re_temp[i])][0] += copy.deepcopy(no_job_data_re_temp[i][0])
            new_no_job_data_re_temp[new_no_car_re_temp.index(no_car_re_temp[i])][1] += copy.deepcopy(no_job_data_re_temp[i][1])

    no_car_re = []
    no_job_data_re = []

    if new_no_car_re_temp != []:
        slow = 0
        temp = new_no_job_data_re_temp[0]
        for i in range(1, len(new_no_car_re_temp)):
            if new_no_car_re_temp[i] != new_no_car_re_temp[slow]:
                no_job_data_re.append(temp)
                no_car_re.append(new_no_car_re_temp[slow])
                temp = [0, 0]
                slow = i

            temp[0] += new_no_job_data_re_temp[i][0]
            temp[1] += new_no_job_data_re_temp[i][1]
        no_job_data_re.append(temp)
        no_car_re.append(new_no_car_re_temp[slow])
    job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, new_no_car_re_temp, no_job_data_re, begin_time, end_time, car_num = copy.deepcopy(job_total), copy.deepcopy(job_type_total), copy.deepcopy(job_re), copy.deepcopy(goods_num_new), copy.deepcopy(out_car), copy.deepcopy(car_type), copy.deepcopy(car_goods_d), copy.deepcopy(new_no_car_re_temp),copy.deepcopy(no_job_data_re), copy.deepcopy(begin_time), copy.deepcopy(end_time), copy.deepcopy(car_num)
    return job_total, job_type_total, job_re, goods_num_new, out_car, car_type, car_goods_d, new_no_car_re_temp,no_job_data_re, begin_time, end_time, car_num


def get_insert_start_time(insert_time, deliver_plan_time, detail_port_num, detail_id_arr, ems_begin_time,
                          EMS_interval_time, zz_interval_time):
    # 得到锁定时间和开始时间
    ems_time_lock = []
    ems_port_lock = []
    zz_time_lock = []
    zz_port_lock = []
    zz_begin_time_c = []
    zz_re = []

    for i in range(len(detail_id_arr)):
        if bool(detail_id_arr[i]):
            if detail_id_arr[i][1] == 0:
                if len(deliver_plan_time[i]) == 2:
                    max_end_time = max(deliver_plan_time[i][0][1], deliver_plan_time[i][1][1])
                    if insert_time >= deliver_plan_time[i][0][0] and insert_time < max_end_time:
                        ems_time_lock.append(deliver_plan_time[i])
                        ems_port_lock.append(detail_port_num[i])
                else:
                    max_end_time = deliver_plan_time[i][0][1]
                    if insert_time >= deliver_plan_time[i][0][0] and insert_time < max_end_time:
                        ems_time_lock.append(deliver_plan_time[i])
                        ems_port_lock.append(detail_port_num[i])

            else:
                if len(deliver_plan_time[i]) == 2:
                    max_end_time = max(deliver_plan_time[i][0][1], deliver_plan_time[i][1][1])
                    if insert_time >= deliver_plan_time[i][0][0] and insert_time < max_end_time:
                        zz_time_lock.append(deliver_plan_time[i])
                        zz_port_lock.append(detail_port_num[i])
                else:
                    max_end_time = deliver_plan_time[i][0][1]
                    if insert_time >= deliver_plan_time[i][0][0] and insert_time < max_end_time:
                        zz_time_lock.append(deliver_plan_time[i])
                        zz_port_lock.append(detail_port_num[i])

    ems_time_lock, ems_port_lock = remove_du(ems_time_lock, ems_port_lock)

    zz_time_lock, zz_port_lock = remove_du(zz_time_lock, zz_port_lock)

    for i in range(len(ems_begin_time)):
        if ems_begin_time[i] < insert_time:
            ems_begin_time[i] = insert_time

    for i in range(len(detail_id_arr)):
        if bool(detail_id_arr[i]):
            if detail_id_arr[i][1] == 0:
                if len(deliver_plan_time[i]) == 2:
                    max_end_time = max(deliver_plan_time[i][0][1], deliver_plan_time[i][1][1])
                else:
                    max_end_time = deliver_plan_time[i][0][1]
                if max_end_time + EMS_interval_time[detail_id_arr[i][0][0]] > ems_begin_time[detail_id_arr[i][0][0]]:
                    ems_begin_time[detail_id_arr[i][0][0]] = max_end_time + EMS_interval_time[detail_id_arr[i][0][0]]

    for i in range(len(detail_id_arr)):
        if bool(detail_id_arr[i]):
            if detail_id_arr[i][0] == 0:
                if len(deliver_plan_time[i]) == 2:
                    max_end_time = max(deliver_plan_time[i][0][1], deliver_plan_time[i][1][1])
                else:
                    max_end_time = deliver_plan_time[i][0][1]
                if max_end_time + zz_interval_time[detail_id_arr[i][1][0]] > insert_time:
                    zz_begin_time_c.append([insert_time, max_end_time + zz_interval_time[detail_id_arr[i][1][0]]])
                    zz_re.append(detail_id_arr[i])

    zz_d1 = {}
    set_1 = set()

    for i in range(len(zz_re)):
        if zz_re[i][1][0] not in set_1:
            set_1.add(zz_re[i][1][0])
            zz_d1[zz_re[i][1][0]] = zz_begin_time_c[i][1]
        else:
            if zz_begin_time_c[i][1] > zz_d1[zz_re[i][1][0]]:
                zz_d1[zz_re[i][1][0]] = zz_begin_time_c[i][1]

    return ems_time_lock, ems_port_lock, zz_time_lock, zz_port_lock, zz_d1, ems_begin_time


def insert_se_solve(job_data, job_type, data_end_start, V_j, c, a_c, dis, zz_car_time, V_EMS_j, t, zz_interval_time,
                    ems_c, ems_time_lock, ems_port_lock, zz_time_lock, zz_port_lock, zz_d1, index_original_zz,
                    insert_time, rong_liang_zz, zhuan_hua_zz, box_flow_value, zz_delivery_count, ems_delivery_count,max_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger):
    """
    该函数用于求解时间窗，输入输出参数解释如下
    :param job_data:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
    :param d_list:EMS货物的截止日期
    :param job_type:EMS货物形态 0可代表栈板，1代表件箱，2代表gtp
    :param data_end_start:各个任务对应的开始时间
    :param sxt:所有自制子任务的开始处理时间和处理结束时间，单位为分钟
    :param sbsj:该项对应某一个自制子任务是否被处理，若为1则被处理，若为0则没被处理
    :param sbc:该项对应自制子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    :param V_j: 不同类型货物对应通道的速度，数量/分钟，0的位置对应栈板，1的位置对应件箱，2的位置对应自制
    :param t:求解时间，若最后无解，则需调大时间
    :return: solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为分钟
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    solution_bool_C_N 方便EMS求解使用的通道参数
    """

    # # 对速度进行折扣处理
    # for v in range(len(V_j)):
    #     if int(V_j[v] * dis) != 0:
    #         V_j[v] = int(V_j[v] * dis)
    #     else:
    #         V_j[v] = 1
    # # 对速度进行折扣处理
    # for v in range(len(V_EMS_j)):
    #     if int(V_EMS_j[v] * dis) != 0:
    #         V_EMS_j[v] = int(V_EMS_j[v] * dis)
    #     else:
    #         V_EMS_j[v] = 1

    # 对速度进行折扣处理

    total_zz_cargo_num,total_ems_cargo_num = get_zz_cargo_num(job_data,job_type,c)

    for v in range(len(V_j)):
        V_j[v] = int(V_j[v] * dis * 10000)

    # 对速度进行折扣处理
    for v in range(len(V_EMS_j)):
        V_EMS_j[v] = int(V_EMS_j[v] * dis * 10000)

    total_C_list = []
    bool_job_list = []
    bool_sub_job_list = []
    job_p_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    solution_bool_C_N = []
    de = []
    rs_c = []
    rs_zz_delivery_count = []
    rs_ems_delivery_count = []
    total_bb = 0
    total_bbb = 0

    model = cp_model.CpModel()




    for i in range(len(job_data)):  # 厂家层级遍历
        j_b = model.NewBoolVar('%d' % i)  # 该厂家的车是否全部排完
        total_bb += j_b
        bool_job_list.append(j_b)
        job_p_sub = []
        C_list = []
        bool_sub_job = []
        bool_sub_ssub_job = []

        ems_c_num_occupy = [[] for _ in range(len(random_ems_index))]
        zz_c_num_occupy = [[] for _ in range(len(random_zz_index))]
        ems_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_ems_index))]
        zz_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_zz_index))]
        ems_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_ems_index))]
        zz_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_zz_index))]

        for j in range(len(job_data[i])):  # 订单层级的遍历
            j_sub_b = model.NewBoolVar('%d_%d' % (i, j))  # 订单是否完成
            bool_sub_job.append(j_sub_b)
            u_bool_sub_sub_job = []
            u_job_p_sub_sub = []
            u_sub_C_list = []
            u_bool_sub_job_se = []


            for k in range(len(job_data[i][j])):  # 车辆层级遍历
                u_j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))  # 车辆是否排入
                u_bool_sub_job_se.append(u_j_sub_b_se)
                bool_sub_sub_job = []
                job_p_sub_sub = []
                sub_C_list = []
                for p in range(len(job_data[i][j][k])):  # 车内部货物类型层级遍历（件箱、栈板）
                    j_sub_sub_b = model.NewBoolVar('%d_%d_%d_%d' % (i, j, k, p))  # 货物是否被分配通道并在交期内处理
                    bool_sub_sub_job.append(j_sub_sub_b)
                    total_bbb += j_sub_sub_b
                    sub_sub_c_list = []
                    sub_sub_p_list = []
                    if zz_car_time[i][j][k][0] < insert_time:
                        a_i = insert_time
                    else:
                        a_i = zz_car_time[i][j][k][0]
                    j_sub_p_s = model.NewIntVar(a_i, max_time,
                                                'p_s_%d_%d_%d_%d' % (i, j, k, p))  # 货物开始处理时间变量
                    j_sub_p_e = model.NewIntVar(a_i, max_time,
                                                'p_e_%d_%d_%d_%d' % (i, j, k, p))  # 货物结束处理时间变量
                    j_sub_p_e_1 = model.NewIntVar(a_i, max_time,
                                                  'p_e1_%d_%d_%d_%d' % (i, j, k, p))  # 用于车辆时间间隔的变量
                    due_data_d = model.NewBoolVar('due_data_d')  # 交期是否满足的变量
                    c_d = model.NewBoolVar('c_d')  # 是否分配通道的变量
                    model.Add(j_sub_p_e <= zz_car_time[i][j][k][1]).OnlyEnforceIf(due_data_d)  # 交期约束
                    model.Add(j_sub_p_e > zz_car_time[i][j][k][1]).OnlyEnforceIf(due_data_d.Not())  # 交期约束
                    sub_sub_p_list.append(j_sub_p_s)
                    sub_sub_p_list.append(j_sub_p_e)
                    sub_sub_p_list.append(j_sub_p_e_1)
                    job_p_sub_sub.append(sub_sub_p_list)
                    if job_type[i][j][k][p] == 0:  # 根据货物类型来查询通道
                        for v in range(len(c[i][j][1])):  # 遍历通道
                            if c[i][j][1][v] == 1:  # 通道可以使用，为0则是被禁用
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, 7))
                                sub_sub_c_list.append(b)
                    else:
                        # 自制件箱的通道有些特殊，自制的通道分为去一楼的和去负一楼的，一楼的通道坏了，现在和EMS的通道共享
                        if c[i][j][0][0] == 1:  # 去负一楼的通道，不用和EMS共享
                            for m in range(len(c[i][j][0])):
                                if c[i][j][0][m] == 1:
                                    b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                    sub_sub_c_list.append(b)
                                    zz_c_num_occupy[m//2].append(b)
                        else:  # 去一楼的，得和EMS共享
                            # cc = [1, 1, 1, 1, 1, 1, 1]
                            cc = ems_c[0][0][0]
                            for m in range(len(cc)):
                                if cc[m] == 1:
                                    b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                    sub_sub_c_list.append(b)
                                    ems_c_num_occupy[m].append(b)

                    model.Add(sum(sub_sub_c_list) <= job_data[i][j][k][p])
                    model.Add(sum(sub_sub_c_list) > 0).OnlyEnforceIf(c_d)  # 分配通道，c_d为1
                    model.Add(sum(sub_sub_c_list) == 0).OnlyEnforceIf(c_d.Not())
                    # model.Add(due_data_d == 1).OnlyEnforceIf(c_d)
                    model.Add(c_d + due_data_d == 2).OnlyEnforceIf(j_sub_sub_b)  # 交期通道两个全满足，货物进去
                    model.Add(c_d + due_data_d < 2).OnlyEnforceIf(j_sub_sub_b.Not())
                    sub_C_list.append(sub_sub_c_list)
                u_job_p_sub_sub.append(job_p_sub_sub)
                u_sub_C_list.append(sub_C_list)
                u_bool_sub_sub_job.append(bool_sub_sub_job)
                model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(
                    u_j_sub_b_se)  # 件箱和栈板全部排入或件箱、栈板排入就代表车排入了
                model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se.Not())

            model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b)  # 车全排入了，就代表订单完成了
            model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b.Not())

            C_list.append(u_sub_C_list)
            bool_sub_ssub_job.append(u_bool_sub_sub_job)
            job_p_sub.append(u_job_p_sub_sub)

        if c[i][0][0][0] == 0:
            if total_ems_cargo_num[i] >0:
                [model.Add(ems_c_occupy_s[v] == sum(ems_c_num_occupy[v])) for v in range(len(ems_c_occupy_s))]
                for v in range(len(ems_c_occupy)):
                    model.Add(ems_c_occupy_s[v] > 0).OnlyEnforceIf(ems_c_occupy[v])
                    model.Add(ems_c_occupy_s[v] <= 0).OnlyEnforceIf(ems_c_occupy[v].Not())
                if total_ems_cargo_num[i] < portEmsLpnNum2:
                    model.Add(sum(ems_c_occupy) <= 1)
                elif total_ems_cargo_num[i] >= portEmsLpnNum2 and total_ems_cargo_num[i] <= portEmsLpnNum3:
                    model.Add(sum(ems_c_occupy) <= 2)
                elif total_ems_cargo_num[i] > portEmsLpnNum3:
                    model.Add(sum(ems_c_occupy) <= 3)
        else:
            if total_zz_cargo_num[i] >0:
                [model.Add(zz_c_occupy_s[v] == sum(zz_c_num_occupy[v])) for v in range(len(zz_c_occupy_s))]
                for v in range(len(zz_c_occupy)):
                    model.Add(zz_c_occupy_s[v] > 0).OnlyEnforceIf(zz_c_occupy[v])
                    model.Add(zz_c_occupy_s[v] <= 0).OnlyEnforceIf(zz_c_occupy[v].Not())
                if total_zz_cargo_num[i] < portSelfLpnNum2:
                    model.Add(sum(zz_c_occupy) <= 1)
                elif total_zz_cargo_num[i] >= portSelfLpnNum2:
                    model.Add(sum(zz_c_occupy) <= 2)

        model.Add(sum(bool_sub_job) == len(bool_sub_job)).OnlyEnforceIf(j_b)  # 所有订单完成了，厂家完成了
        model.Add(sum(bool_sub_job) < len(bool_sub_job)).OnlyEnforceIf(j_b.Not())

        total_C_list.append(C_list)
        bool_sub_job_list.append(bool_sub_ssub_job)
        job_p_list.append(job_p_sub)

    # 资源占用
    if bool(ems_time_lock):
        for i in range(len(ems_time_lock)):
            for k in range(len(ems_port_lock[i])):
                if k < len(ems_c[0][0][0]):
                    if ems_port_lock[i][k] == 1 and (int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0])) > 0:
                        x_s = model.NewConstant(int(ems_time_lock[i][0][0]))
                        ii = model.NewConstant(int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0]))
                        x_e = model.NewConstant(int(ems_time_lock[i][0][1]))
                        y_s = model.NewConstant(a_c + 1 + k)
                        iii = model.NewConstant(1)
                        y_e = model.NewConstant(a_c + 1 + 1 + k)

                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                        x_intervals.append(x_ii)
                        rs_ems_delivery_count.append(x_ii)
                        y_intervals.append(y_ii)
                else:
                    if ems_port_lock[i][k] == 1:
                        if ems_time_lock[i] == 2:
                            if (int(ems_time_lock[i][1][1]) - int(ems_time_lock[i][1][0])) > 0:
                                x_s = model.NewConstant(int(ems_time_lock[i][1][0]))
                                ii = model.NewConstant(int(ems_time_lock[i][1][1]) - int(ems_time_lock[i][1][0]))
                                x_e = model.NewConstant(int(ems_time_lock[i][1][1]))
                                y_s = model.NewConstant(k - len(ems_c[0][0][0]))
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(k - len(ems_c[0][0][0]) + 1)

                                x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                                y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                                x_intervals.append(x_ii)
                                rs_ems_delivery_count.append(x_ii)
                                y_intervals.append(y_ii)
                        else:
                            if (int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0])) > 0:
                                x_s = model.NewConstant(int(ems_time_lock[i][0][0]))
                                ii = model.NewConstant(int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0]))
                                x_e = model.NewConstant(int(ems_time_lock[i][0][1]))
                                y_s = model.NewConstant(k - len(ems_c[0][0][0]))
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(k - len(ems_c[0][0][0]) + 1)

                                x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                                y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                                rs_ems_delivery_count.append(x_ii)
                                x_intervals.append(x_ii)
                                y_intervals.append(y_ii)

    if bool(zz_time_lock):
        for i in range(len(zz_time_lock)):
            if len(zz_port_lock[i]) == (1 + len(c[0][0][1])):
                for j in range(len(zz_port_lock[i])):
                    if j < 1:
                        if zz_port_lock[i][j] == 1 and (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                            x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                            ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                            x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                            y_s = model.NewConstant(a_c + j)
                            iii = model.NewConstant(1)
                            y_e = model.NewConstant(a_c + 1 + j)

                            x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                            y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                            rs_zz_delivery_count.append(x_ii)
                            x_intervals.append(x_ii)
                            y_intervals.append(y_ii)
                    else:
                        if zz_port_lock[i][j] == 1:
                            if len(zz_time_lock[i]) == 2:
                                if (int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][1][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][1][1]))
                                    y_s = model.NewConstant(j - 1)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)
                            else:
                                if (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                                    y_s = model.NewConstant(j - 1)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)
            elif len(zz_port_lock[i]) == (len(ems_c[0][0][0]) + len(c[0][0][1])):
                for j in range(len(zz_port_lock[i])):
                    if j < len(ems_c[0][0][0]):
                        if zz_port_lock[i][j] == 1 and (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                            x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                            ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                            x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                            y_s = model.NewConstant(a_c + 1 + j)
                            iii = model.NewConstant(1)
                            y_e = model.NewConstant(a_c + 1 + 1 + j)

                            x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                            y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                            rs_zz_delivery_count.append(x_ii)
                            x_intervals.append(x_ii)
                            y_intervals.append(y_ii)
                    else:
                        if zz_port_lock[i][j] == 1:
                            if len(zz_time_lock[i]) == 2:
                                if (int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][1][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][1][1]))
                                    y_s = model.NewConstant(j - len(ems_c[0][0][0]))
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j - len(ems_c[0][0][0]) + 1)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)
                            else:
                                if (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                                    y_s = model.NewConstant(j - len(ems_c[0][0][0]))
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j - len(ems_c[0][0][0]) + 1)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)

    # 接下来分配通达，并计算运输时间
    for i in range(len(job_data)):  # 厂家层级遍历
        for j in range(len(job_data[i])):  # 订单层级遍历
            x_tt_intervals = []
            zz_i_index = index_original_zz[i]
            if zz_i_index in zz_d1:
                x_i_s = model.NewConstant(int(insert_time))
                zz_ii = model.NewConstant(int(zz_d1[zz_i_index]) - int(insert_time))
                x_i_e = model.NewConstant(int(zz_d1[zz_i_index]))
                xi_ii = model.NewOptionalIntervalVar(x_i_s, zz_ii, x_i_e, 1, 'x_ziizii%d' % i)
                x_tt_intervals.append(xi_ii)
            for e in range(len(job_data[i][j])):  # 车辆遍历
                ini = []
                cd = []
                mm_v = model.NewIntVar(0, max_time, 'p_e_%d_%d' % (i, j))
                for p in range(len(job_data[i][j][e])):  # 货物类型遍历
                    total_interval = 0  # 速度总和的变量
                    if job_type[i][j][e][p] == 1 and c[i][j][0][0] == 0:  # 和EMS共享通道
                        for k in range(len(total_C_list[i][j][e][p])):
                            total_interval += total_C_list[i][j][e][p][k] * V_EMS_j[1]
                    else:
                        for k in range(len(total_C_list[i][j][e][p])):  # 去负一楼
                            total_interval += total_C_list[i][j][e][p][k] * V_j[job_type[i][j][e][p]]
                    t_i = model.NewIntVar(1, 99999999, 't_i_%d' % j)
                    model.Add(t_i == total_interval + 1)  # 速度计算待处理
                    I = model.NewIntVar(0, 99999999, 'In_%d' % j)
                    model.AddDivisionEquality(I, job_data[i][j][e][p] * 10000, t_i)
                    ini.append(job_p_list[i][j][e][p][0])
                    cd.append(I)

                    kk = 0
                    if job_type[i][j][e][p] == 1:  # 件箱货物形态
                        if c[i][j][0][0] == 1:  # 去负一楼
                            for u in range(len(c[i][j][0])):
                                if c[i][j][0][u] == 1:  # 通道可用，构建矩形
                                    y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, u))
                                    j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                     job_p_list[i][j][e][p][1],
                                                                                     total_C_list[i][j][e][p][u // 2],
                                                                                     'p_%d_%d_%d_%d' % (
                                                                                     i, j, p, u // 2))

                                    j_sub_c_intervals = model.NewOptionalIntervalVar(a_c + u, 1, y_end,
                                                                                     total_C_list[i][j][e][p][u // 2],
                                                                                     'c_%d_%d_%d_%d' % (
                                                                                     i, j, p, u // 2))
                                    kk += 1
                                    rs_c.append(j_sub_p_intervals)
                                    rs_zz_delivery_count.append(j_sub_p_intervals)
                                    de.append(int(V_j[2]))
                                    x_intervals.append(j_sub_p_intervals)
                                    y_intervals.append(j_sub_c_intervals)
                        else:  # 和EMS共享
                            # ccc = [1, 1, 1, 1, 1, 1, 1]  # 需修改，待处理
                            ccc = ems_c[0][0][0]
                            for u in range(len(ccc)):
                                if ccc[u] == 1:  # 通道可用，构建矩形
                                    y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, u))
                                    j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                     job_p_list[i][j][e][p][1],
                                                                                     total_C_list[i][j][e][p][u],
                                                                                     'p_%d_%d_%d_%d' % (i, j, p, u))

                                    j_sub_c_intervals = model.NewOptionalIntervalVar(a_c + u + 1, 1, y_end,
                                                                                     total_C_list[i][j][e][p][u],
                                                                                     'c_%d_%d_%d_%d' % (i, j, p, u))
                                    kk += 1
                                    rs_c.append(j_sub_p_intervals)
                                    rs_ems_delivery_count.append(j_sub_p_intervals)
                                    de.append(int(V_j[1]))
                                    x_intervals.append(j_sub_p_intervals)
                                    y_intervals.append(j_sub_c_intervals)

                    else:  # 栈板货物形态
                        for u in range(len(c[i][j][1])):
                            if c[i][j][1][u] == 1:  # 口可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))

                                j_sub_c_intervals = model.NewOptionalIntervalVar(u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                if len(ini) == 2:  # 若一辆车有两种类型的货物
                    model.Add(ini[0] == ini[1])  # 限制开始处理时间相同
                    model.Add(bool_sub_job_list[i][j][e][0] == bool_sub_job_list[i][j][e][1])
                    I_v = model.NewIntVar(0, 99999999, 'p_e_%d_%d' % (i, j))
                    model.AddMaxEquality(I_v, cd)
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], I_v + int(zz_interval_time[i]) + 1, mm_v,
                                                                       bool_sub_job_list[i][j][e][0],
                                                                       '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)
                else:
                    j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], cd[0] + int(zz_interval_time[i]) + 1,
                                                                       mm_v,
                                                                       bool_sub_job_list[i][j][e][0],
                                                                       '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)

            model.AddNoOverlap(x_tt_intervals)

    load_rate = []

    for i in range(len(job_data)):
        sub_load_rate = []
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                total_goods = 0
                for p in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][p] == 0:
                        total_goods += job_data[i][j][k][p] * zhuan_hua_zz[i]
                    else:
                        total_goods += job_data[i][j][k][p]
                sub_load_rate.append(total_goods / rong_liang_zz[i])
        load_rate.append(sub_load_rate)

    load_rate_index = []

    for i in range(len(load_rate)):
        sub_load_rate = sorted(enumerate(load_rate[i]), key=lambda x: x[1], reverse=True)
        sub_load_index = [ind for ind, _ in sub_load_rate]
        load_rate_index.append(sub_load_index)

    for i in range(len(load_rate_index)):
        if len(load_rate_index[i]) > 1:
            for k in range(len(load_rate_index[i]) - 1):
                model.Add(
                    job_p_list[i][0][load_rate_index[i][k]][0][0] < job_p_list[i][0][load_rate_index[i][k + 1]][0][0])




    # for i in range(len(job_p_list)):
    #     for j in range(len(job_p_list[i])):
    #         if len(job_p_list[i][j]) > 1:
    #             for k in range(len(job_p_list[i][j]) - 1):
    #                 model.Add(job_p_list[i][j][k][0][0] < job_p_list[i][j][k + 1][0][0])
    de_zz_delivery_count = [1] * len(rs_zz_delivery_count)
    de_ems_delivery_count = [1] * len(rs_ems_delivery_count)
    model.AddNoOverlap2D(x_intervals, y_intervals)
    model.AddCumulative(rs_c, de, int(10000 * box_flow_value * dis))  # 件箱库流量约束
    model.AddCumulative(rs_zz_delivery_count, de_zz_delivery_count, zz_delivery_count)
    model.AddCumulative(rs_ems_delivery_count, de_ems_delivery_count, ems_delivery_count)
    model.Maximize(total_bbb)  # 最大化排进去的车
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8

    solver.parameters.max_time_in_seconds = t

    status = solver.Solve(model)

    # 得到最终的解
    solution_find = False
    if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
        solution_find = True
        if status == cp_model.OPTIMAL:
            logger.info("自制时间窗模型求得最优解")
        if status == cp_model.FEASIBLE:
            logger.info("自制时间窗模型求得次优解")
    if solution_find == False:
        logger.error("自制时间窗模型无解")



    for i in range(len(job_data)):
        solu_x_sub = []
        for j in range(len(job_data[i])):
            u_solu_x_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    solution_x = []
                    if not solution_find:
                        solution_x.append(0)
                        solution_x.append(0)
                    else:
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][0]))
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][1]))
                    so.append(solution_x)
                u_solu_x_sub.append(so)
            solu_x_sub.append(u_solu_x_sub)
        solution_x_total.append(solu_x_sub)

    for i in range(len(job_data)):
        solu_bool_sub = []
        for j in range(len(job_data[i])):
            u_solu_bool_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    if not solution_find:
                        so.append(0)
                    else:
                        so.append(solver.Value(bool_sub_job_list[i][j][g][k]))
                u_solu_bool_sub.append(so)
            solu_bool_sub.append(u_solu_bool_sub)
        solution_bool_sub_job.append(solu_bool_sub)

    for i in range(len(job_data)):
        solu_C_sub = []
        for j in range(len(job_data[i])):
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])):
                u_solu_C_sub_sub = []
                if len(job_data[i][j][e]) == 2:
                    so = []
                    c_index_list = []
                    for p in range(len(job_data[i][j][e])):
                        # so = []
                        if job_type[i][j][e][p] == 1:
                            c_index_list.append(p)

                        # if job_type[i][j][e][p] == 0:
                        #     c_index_list.append(p)

                    for p in range(len(job_data[i][j][e])):
                        # so = []
                        # if job_type[i][j][e][p] == 1:
                        #     c_index_list.append(p)

                        if job_type[i][j][e][p] == 0:
                            c_index_list.append(p)

                    for w in range(len(total_C_list[i][j][e][c_index_list[0]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[0]][w]))
                    if (c[i][0][0][0] == 0):
                        so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                    else:
                        so = copy.deepcopy([so[random_zz_index[i]] for i in range(len(random_zz_index))])
                    for w in range(len(total_C_list[i][j][e][c_index_list[1]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[1]][w]))
                    u_solu_C_sub_sub.append(so)
                    #

                else:
                    so = []
                    if job_type[i][j][e][0] == 1:  # 如果是件箱
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        if (c[i][0][0][0] == 0):
                            so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                        else:
                            so = copy.deepcopy([so[random_zz_index[i]] for i in range(len(random_zz_index))])
                        so = so + [0] * len(c[0][0][1])
                        u_solu_C_sub_sub.append(so)
                    else:  # 如果是栈板
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        if (c[i][0][0][0] == 1):
                            so = [0] * (len(c[i][0][0]) // 2) + so
                        else:
                            so = [0] * len(ems_c[0][0][0]) + so
                        u_solu_C_sub_sub.append(so)
                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C.append(solu_C_sub)

    for i in range(len(job_data)):
        solu_C_sub = []
        for j in range(len(job_data[i])):
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])):
                u_solu_C_sub_sub = []
                for p in range(len(job_data[i][j][e])):
                    so = []
                    k = 0
                    if job_type[i][j][e][p] == 1:
                        for w in range(len(total_C_list[i][j][e][p])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][p][w]))

                    else:
                        for z in range(len(c[i][j][1])):
                            if c[i][j][1][z] == 1:
                                if not solution_find:
                                    so.append(0)
                                else:
                                    so.append(solver.Value(total_C_list[i][j][e][p][k]))
                                k += 1
                            else:
                                so.append(0)
                    u_solu_C_sub_sub.append(so)
                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C_N.append(solu_C_sub)

    return solution_x_total, solution_bool_sub_job, solution_bool_C, solution_bool_C_N


def insert_solve(job_data, d_list, job_type, data_end_start, sxt, sbsj, sbc, s_job_type, V_j, s_c,c, p_num, a_c, dis, t,
                 ems_interval_time, ems_time_lock, ems_port_lock, zz_time_lock, zz_port_lock, rong_liang_EMS,
                 zhuan_hua_EMS, box_flow_value, zz_delivery_count, ems_delivery_count,ems_priority,max_time,work_time_list, interval_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger):
    """
    该函数用于求解时间窗，输入输出参数解释如下
    :param job_data:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
    :param d_list:EMS货物的截止日期
    :param job_type:EMS货物形态 0可代表栈板，1代表件箱，2代表gtp
    :param data_end_start:各个任务对应的开始时间
    :param sxt:所有自制子任务的开始处理时间和处理结束时间，单位为分钟
    :param sbsj:该项对应某一个自制子任务是否被处理，若为1则被处理，若为0则没被处理
    :param sbc:该项对应自制子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    :param s_job_type: 自制的货物形态，0可代表栈板，1代表件箱
    :param V_j: 不同类型货物对应通道的速度，数量/分钟，0的位置对应栈板，1的位置对应件箱，2的位置对应自制
    :param c: 可用的通道
    :param p_num: 所有件箱的通道
    :param a_c: 所有栈板的通道
    :param t:求解时间，若最后无解，则需调大时间
    :return: solution_x_total 所有子任务的开始处理时间和处理结束时间，单位为分钟
    solution_bool_sub_job 该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理
    solution_bool_C 该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用
    """
    # # 对速度进行折扣处理
    # for v in range(len(V_j)):
    #     if int(V_j[v] * dis) != 0:
    #         V_j[v] = int(V_j[v] * dis)
    #     else:
    #         V_j[v] = 1
    total_ems_cargo_num = get_ems_cargo_num(job_data, job_type)

    # 对速度进行折扣处理
    for v in range(len(V_j)):
        V_j[v] = int(V_j[v] * dis * 10000)

    total_C_list = []
    bool_job_list = []
    bool_sub_job_list = []
    job_p_list = []
    x_intervals = []
    y_intervals = []
    solution_x_total = []
    solution_bool_sub_job = []
    solution_bool_C = []
    de = []
    rs_c = []
    rs_zz_delivery_count = []
    rs_ems_delivery_count = []
    total_bb = 0
    total_bbb = 0
    min_end_time = []
    model = cp_model.CpModel()


    for i in range(len(job_data)):  # 厂家层级遍历
        ts = data_end_start[i]
        j_b = model.NewBoolVar('%d' % i)  # 该厂家的车是否全部排完
        total_bb += j_b
        bool_job_list.append(j_b)
        job_p_sub = []
        C_list = []
        bool_sub_job = []
        bool_sub_ssub_job = []

        ems_c_num_occupy = [[] for _ in range(len(random_ems_index))]
        ems_c_occupy_s = [model.NewIntVar(0, 100, 'p_e_%d' % (i)) for i in range(len(random_ems_index))]
        ems_c_occupy = [model.NewBoolVar('ocp_%d' % (i)) for i in range(len(random_ems_index))]

        for j in range(len(job_data[i])):  # 订单层级的遍历
            j_sub_b = model.NewBoolVar('%d_%d' % (i, j))  # 订单是否完成
            bool_sub_job.append(j_sub_b)
            u_bool_sub_sub_job = []
            u_job_p_sub_sub = []
            u_sub_C_list = []
            u_bool_sub_job_se = []


            for k in range(len(job_data[i][j])):  # 车辆层级遍历
                u_j_sub_b_se = model.NewBoolVar('%d_%d_%d' % (i, j, k))
                u_bool_sub_job_se.append(u_j_sub_b_se)

                bool_sub_sub_job = []
                job_p_sub_sub = []
                sub_C_list = []
                for p in range(len(job_data[i][j][k])):  # 车内部货物类型层级遍历（件箱、栈板）
                    j_sub_sub_b = model.NewBoolVar('%d_%d_%d_%d' % (i, j, k, p))  # 货物是否被分配通道并在交期内处理
                    bool_sub_sub_job.append(j_sub_sub_b)
                    total_bbb += j_sub_sub_b
                    sub_sub_c_list = []
                    sub_sub_p_list = []
                    j_sub_p_s = model.NewIntVar(int(ts), max_time, 'p_s_%d_%d_%d_%d' % (i, j, k, p))  # 货物开始处理时间变量
                    j_sub_p_e = model.NewIntVar(int(ts), max_time, 'p_e_%d_%d_%d_%d' % (i, j, k, p))  # 货物结束处理时间变量
                    j_sub_p_e_1 = model.NewIntVar(int(ts), max_time, 'p_e1_%d_%d_%d_%d' % (i, j, k, p))  # 用于车辆时间间隔的变量
                    due_data_d = model.NewBoolVar('due_data_d')  # 交期是否满足的变量
                    min_end_time.append(j_sub_p_e)
                    c_d = model.NewBoolVar('c_d')  # 是否分配通道的变量
                    model.Add(j_sub_p_e <= d_list[i]).OnlyEnforceIf(due_data_d)  # 交期约束
                    model.Add(j_sub_p_e > d_list[i]).OnlyEnforceIf(due_data_d.Not())  # 交期约束
                    sub_sub_p_list.append(j_sub_p_s)
                    sub_sub_p_list.append(j_sub_p_e)
                    sub_sub_p_list.append(j_sub_p_e_1)
                    job_p_sub_sub.append(sub_sub_p_list)
                    if job_type[i][j][k][p] == 0:  # 根据货物类型来查询通道
                        for v in range(len(c[i][j][1])):  # 遍历通道
                            if c[i][j][1][v] == 1:  # 通道可以使用，为0则是被禁用
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, 7))
                                sub_sub_c_list.append(b)
                    else:
                        for m in range(len(c[i][j][0])):
                            if c[i][j][0][m] == 1:
                                b = model.NewBoolVar('%d_%d_%d_%d_%d' % (i, j, k, p, m))
                                sub_sub_c_list.append(b)
                                ems_c_num_occupy[m].append(b)
                    model.Add(sum(sub_sub_c_list) <= job_data[i][j][k][p])
                    model.Add(sum(sub_sub_c_list) > 0).OnlyEnforceIf(c_d)  # 分配通道，c_d为1
                    model.Add(sum(sub_sub_c_list) == 0).OnlyEnforceIf(c_d.Not())
                    # model.Add(due_data_d == 1).OnlyEnforceIf(c_d)
                    model.Add(c_d + due_data_d == 2).OnlyEnforceIf(j_sub_sub_b)  # 交期通道两个全满足，货物进去
                    model.Add(c_d + due_data_d < 2).OnlyEnforceIf(j_sub_sub_b.Not())
                    sub_C_list.append(sub_sub_c_list)
                u_job_p_sub_sub.append(job_p_sub_sub)
                u_sub_C_list.append(sub_C_list)
                u_bool_sub_sub_job.append(bool_sub_sub_job)
                model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(
                    u_j_sub_b_se)  # 件箱和栈板全部排入或件箱、栈板排入就代表车排入了
                model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(u_j_sub_b_se.Not())

            model.Add(sum(u_bool_sub_job_se) == len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b)  # 车全排入了，就代表订单完成了
            model.Add(sum(u_bool_sub_job_se) < len(u_bool_sub_job_se)).OnlyEnforceIf(j_sub_b.Not())

            C_list.append(u_sub_C_list)
            bool_sub_ssub_job.append(u_bool_sub_sub_job)
            job_p_sub.append(u_job_p_sub_sub)
            # model.Add(sum(bool_sub_sub_job) == len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b)
            # model.Add(sum(bool_sub_sub_job) < len(bool_sub_sub_job)).OnlyEnforceIf(j_sub_b.Not())

        if total_ems_cargo_num[i] >0:
            [model.Add(ems_c_occupy_s[v] == sum(ems_c_num_occupy[v])) for v in range(len(ems_c_occupy_s))]
            for v in range(len(ems_c_occupy)):
                model.Add(ems_c_occupy_s[v] > 0).OnlyEnforceIf(ems_c_occupy[v])
                model.Add(ems_c_occupy_s[v] <= 0).OnlyEnforceIf(ems_c_occupy[v].Not())
            if total_ems_cargo_num[i] <= portEmsLpnNum2:
                model.Add(sum(ems_c_occupy) <= 1)
            if total_ems_cargo_num[i] > portEmsLpnNum2 and total_ems_cargo_num[i] <= portEmsLpnNum3:
                model.Add(sum(ems_c_occupy) <= 2)
            if total_ems_cargo_num[i] >= portEmsLpnNum3:
                model.Add(sum(ems_c_occupy) <= 3)

        model.Add(sum(bool_sub_job) == len(bool_sub_job)).OnlyEnforceIf(j_b)  # 所有订单完成了，厂家完成了
        model.Add(sum(bool_sub_job) < len(bool_sub_job)).OnlyEnforceIf(j_b.Not())

        total_C_list.append(C_list)
        bool_sub_job_list.append(bool_sub_ssub_job)
        job_p_list.append(job_p_sub)

    # 资源占用
    if bool(ems_time_lock):
        for i in range(len(ems_time_lock)):
            for k in range(len(ems_port_lock[i])):
                if k < len(c[0][0][0]):
                    if ems_port_lock[i][k] == 1 and (int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0])) > 0:
                        x_s = model.NewConstant(int(ems_time_lock[i][0][0]))
                        ii = model.NewConstant(int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0]))
                        x_e = model.NewConstant(int(ems_time_lock[i][0][1]))
                        y_s = model.NewConstant(a_c + 1 + k)
                        iii = model.NewConstant(1)
                        y_e = model.NewConstant(a_c + 1 + 1 + k)

                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                        rs_ems_delivery_count.append(x_ii)
                        x_intervals.append(x_ii)
                        y_intervals.append(y_ii)

                else:
                    if ems_port_lock[i][k] == 1:
                        if len(ems_time_lock[i]) == 2:
                            if (int(ems_time_lock[i][1][1]) - int(ems_time_lock[i][1][0])) > 0:
                                x_s = model.NewConstant(int(ems_time_lock[i][1][0]))
                                ii = model.NewConstant(int(ems_time_lock[i][1][1]) - int(ems_time_lock[i][1][0]))
                                x_e = model.NewConstant(int(ems_time_lock[i][1][1]))
                                y_s = model.NewConstant(k - len(c[0][0][0]))
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(k - len(c[0][0][0]) + 1)

                                x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                                y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                                rs_ems_delivery_count.append(x_ii)
                                x_intervals.append(x_ii)
                                y_intervals.append(y_ii)

                        else:
                            if (int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0])) > 0:
                                x_s = model.NewConstant(int(ems_time_lock[i][0][0]))
                                ii = model.NewConstant(int(ems_time_lock[i][0][1]) - int(ems_time_lock[i][0][0]))
                                x_e = model.NewConstant(int(ems_time_lock[i][0][1]))
                                y_s = model.NewConstant(k - len(c[0][0][0]))
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(k - len(c[0][0][0]) + 1)

                                x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_ii%d' % i)
                                y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_ii%d' % i)
                                rs_ems_delivery_count.append(x_ii)
                                x_intervals.append(x_ii)
                                y_intervals.append(y_ii)

    if bool(zz_time_lock):
        for i in range(len(zz_time_lock)):
            if len(zz_port_lock[i]) == (len(c[0][0][0]) + len(c[0][0][1])):
                for j in range(len(zz_port_lock[i])):
                    if j < len(c[0][0][0]):
                        if zz_port_lock[i][j] == 1 and (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                            x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                            ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                            x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                            y_s = model.NewConstant(a_c + 1 + j)
                            iii = model.NewConstant(1)
                            y_e = model.NewConstant(a_c + 1 + 1 + j)

                            x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                            y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                            rs_zz_delivery_count.append(x_ii)
                            x_intervals.append(x_ii)
                            y_intervals.append(y_ii)
                    else:
                        if zz_port_lock[i][j] == 1:
                            if len(zz_time_lock[i]) == 2:
                                if (int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][1][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][1][1]) - int(zz_time_lock[i][1][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][1][1]))
                                    y_s = model.NewConstant(j - len(c[0][0][0]))
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j - len(c[0][0][0]) + 1)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)
                            else:
                                if (int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0])) > 0:
                                    x_s = model.NewConstant(int(zz_time_lock[i][0][0]))
                                    ii = model.NewConstant(int(zz_time_lock[i][0][1]) - int(zz_time_lock[i][0][0]))
                                    x_e = model.NewConstant(int(zz_time_lock[i][0][1]))
                                    y_s = model.NewConstant(j - len(c[0][0][0]))
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(j - len(c[0][0][0]) + 1)

                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, 1, 'x_zzii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, 1, 'y_zzii%d' % i)
                                    rs_zz_delivery_count.append(x_ii)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)

    # 之前自制的求解，在此处作为常数矩形
    for g in range(len(sxt)):
        for i in range(len(sxt[g])):
            for k in range(len(sxt[g][i])):
                for p in range(len(sxt[g][i][k])):
                    if s_job_type[g][i][k][p] == 1:# 如果是件箱
                        if s_c[g][0][0][0] == 1: # 负一楼
                            for l in range(len(sbc[g][i][k][p])):
                                if sbc[g][i][k][p][l]: # 如果通道启用
                                    x_s = model.NewConstant(sxt[g][i][k][p][0])
                                    ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                    x_e = model.NewConstant(sxt[g][i][k][p][1])
                                    y_s = model.NewConstant(l + p_num + a_c)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(l + p_num + a_c + 1)
                                    if sbsj[g][i][k][p] == 1:
                                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p],
                                                                            'x_ii%d' % i)
                                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p],
                                                                            'y_ii%d' % i)
                                        x_intervals.append(x_ii)
                                        y_intervals.append(y_ii)
                                        de.append(V_j[2])
                                        rs_c.append(x_ii)
                                        rs_zz_delivery_count.append(x_ii)
                        else:
                            for l in range(len(sbc[g][i][k][p])):
                                if sbc[g][i][k][p][l]:
                                    x_s = model.NewConstant(sxt[g][i][k][p][0])
                                    ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                    x_e = model.NewConstant(sxt[g][i][k][p][1])
                                    y_s = model.NewConstant(l)
                                    iii = model.NewConstant(1)
                                    y_e = model.NewConstant(l + 1)
                                    if sbsj[g][i][k][p] == 1:
                                        x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p],
                                                                            'x_ii%d' % i)
                                        y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p],
                                                                            'y_ii%d' % i)
                                        x_intervals.append(x_ii)
                                        y_intervals.append(y_ii)
                                        de.append(V_j[1])
                                        rs_c.append(x_ii)
                                        rs_ems_delivery_count.append(x_ii)
                    else:
                        for l in range(len(sbc[g][i][k][p])):
                            if sbc[g][i][k][p][l]:
                                x_s = model.NewConstant(sxt[g][i][k][p][0])
                                ii = model.NewConstant(sxt[g][i][k][p][1] - sxt[g][i][k][p][0])
                                x_e = model.NewConstant(sxt[g][i][k][p][1])
                                y_s = model.NewConstant(l + p_num)
                                iii = model.NewConstant(1)
                                y_e = model.NewConstant(l + p_num + 1)
                                if sbsj[g][i][k][p] == 1:
                                    x_ii = model.NewOptionalIntervalVar(x_s, ii, x_e, sbsj[g][i][k][p], 'x_ii%d' % i)
                                    y_ii = model.NewOptionalIntervalVar(y_s, iii, y_e, sbsj[g][i][k][p], 'y_ii%d' % i)
                                    x_intervals.append(x_ii)
                                    y_intervals.append(y_ii)

    # 接下来分配通达，并计算运输时间
    for i in range(len(job_data)):  # 厂家层级遍历
        for j in range(len(job_data[i])):  # 订单层级遍历
            x_tt_intervals = []
            for e in range(len(job_data[i][j])):  # 车辆遍历
                ini = []
                cd = []
                mm_v = model.NewIntVar(0, max_time, 'p_e_%d_%d_%d' % (i, j,e))
                itv2 = model.NewIntVar(-999999999, 999999999, 'itv2_%d_%d_%d' % (i, j, e))
                itv3 = model.NewIntVar(0, 999999999, 'itv3_%d_%d_%d' % (i, j, e))
                itv4 = model.NewIntVar(0, 999999999, 'itv4_%d_%d_%d' % (i, j, e))
                ems_itv = model.NewIntVar(0, 999999999, 'ems_itv_%d_%d_%d' % (i, j, e))
                for p in range(len(job_data[i][j][e])):  # 货物类型遍历
                    total_interval = 0  # 速度总和的变量
                    for k in range(len(total_C_list[i][j][e][p])):
                        total_interval += total_C_list[i][j][e][p][k] * V_j[job_type[i][j][e][p]]
                    t_i = model.NewIntVar(1, 99999999, 't_i_%d' % j)
                    model.Add(t_i == total_interval + 1)  # 速度计算，待处理
                    I = model.NewIntVar(0, 99999999, 'In_%d' % j)
                    model.AddDivisionEquality(I, job_data[i][j][e][p] * 10000, t_i)
                    ini.append(job_p_list[i][j][e][p][0])
                    cd.append(I)

                    kk = 0
                    if job_type[i][j][e][p] == 1:  # 件箱货物形态
                        for u in range(len(c[i][j][0])):
                            if c[i][j][0][u] == 1:  # 通道可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))
                                j_sub_c_intervals = model.NewOptionalIntervalVar(u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                rs_c.append(j_sub_p_intervals)
                                rs_ems_delivery_count.append(j_sub_p_intervals)
                                de.append(int(V_j[1]))
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                    else:
                        for u in range(len(c[i][j][1])):
                            if c[i][j][1][u] == 1:  # 通道可用，构建矩形
                                y_end = model.NewIntVar(1, 999, 'y_end_%d%d%d' % (i, j, kk))
                                j_sub_p_intervals = model.NewOptionalIntervalVar(job_p_list[i][j][e][p][0], I + 1,
                                                                                 job_p_list[i][j][e][p][1],
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'p_%d_%d_%d_%d' % (i, j, p, kk))
                                j_sub_c_intervals = model.NewOptionalIntervalVar(p_num + u, 1, y_end,
                                                                                 total_C_list[i][j][e][p][kk],
                                                                                 'c_%d_%d_%d_%d' % (i, j, p, kk))
                                kk += 1
                                x_intervals.append(j_sub_p_intervals)
                                y_intervals.append(j_sub_c_intervals)

                if len(ini) == 2:  # 若一辆车有两种类型的货物
                    model.Add(ini[0] == ini[1])  # 限制开始处理时间相同
                    model.Add(bool_sub_job_list[i][j][e][0] == bool_sub_job_list[i][j][e][1])
                    I_v = model.NewIntVar(0, 99999999, 'p_e_%d_%d' % (i, j))
                    model.AddMaxEquality(I_v, cd)

                    if len(interval_time) > 0:
                        real_time_bool_var = 0
                        for kt in range(len(interval_time)):
                            it_bool_val = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            it_bool_val2 = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            rag11 = model.NewBoolVar('rag11_%d_%d%d%d' % (i, j, e, kt))
                            rag12 = model.NewBoolVar('rag12_%d_%d%d%d' % (i, j, e, kt))
                            rag13 = model.NewBoolVar('rag13_%d_%d%d%d' % (i, j, e, kt))
                            model.Add(ini[0] < work_time_list[kt][1]).OnlyEnforceIf(rag11)
                            model.Add(ini[0] >= work_time_list[kt][1]).OnlyEnforceIf(rag11.Not())
                            model.Add(mm_v >= work_time_list[kt + 1][0]).OnlyEnforceIf(rag12)
                            model.Add(mm_v < work_time_list[kt + 1][0]).OnlyEnforceIf(rag12.Not())
                            model.Add(ini[0] + I_v < work_time_list[kt][1]).OnlyEnforceIf(rag13)
                            model.Add(ini[0] + I_v >= work_time_list[kt][1]).OnlyEnforceIf(rag13.Not())
                            model.AddMultiplicationEquality(it_bool_val, [rag11, rag12])
                            model.AddMultiplicationEquality(it_bool_val2, [it_bool_val, rag13])
                            real_time_bool_var += it_bool_val2 * interval_time[kt]

                        model.Add(itv2 == int(ems_interval_time[i]) - real_time_bool_var)
                        model.AddMaxEquality(itv3, (0, itv2))
                        model.Add(itv4 >= itv3)
                        model.Add(itv4 <= int(ems_interval_time[i]))
                        model.Add(ems_itv == I_v + itv4 + 1)
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], ems_itv,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    else:
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                                                                           I_v + int(ems_interval_time[i]) + 1,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量

                    x_tt_intervals.append(j_sub_p_I_intervals)
                else:
                    if len(interval_time) > 0:
                        real_time_bool_var = 0
                        for kt in range(len(interval_time)):
                            it_bool_val = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            it_bool_val2 = model.NewBoolVar('ibv_%d_%d%d%d' % (i, j, e, kt))
                            rag11 = model.NewBoolVar('rag11_%d_%d%d%d' % (i, j, e, kt))
                            rag12 = model.NewBoolVar('rag12_%d_%d%d%d' % (i, j, e, kt))
                            rag13 = model.NewBoolVar('rag13_%d_%d%d%d' % (i, j, e, kt))
                            model.Add(ini[0] < work_time_list[kt][1]).OnlyEnforceIf(rag11)
                            model.Add(ini[0] >= work_time_list[kt][1]).OnlyEnforceIf(rag11.Not())
                            model.Add(mm_v >= work_time_list[kt][1]).OnlyEnforceIf(rag12)
                            model.Add(mm_v < work_time_list[kt][1]).OnlyEnforceIf(rag12.Not())
                            model.Add(ini[0] +cd[0] < work_time_list[kt][1]).OnlyEnforceIf(rag13)
                            model.Add(ini[0] +cd[0] >= work_time_list[kt][1]).OnlyEnforceIf(rag13.Not())
                            model.AddMultiplicationEquality(it_bool_val, [rag11, rag12])
                            model.AddMultiplicationEquality(it_bool_val2, [it_bool_val, rag13])
                            real_time_bool_var += it_bool_val2 * interval_time[kt]

                        model.Add(itv2 == int(ems_interval_time[i]) - real_time_bool_var)
                        model.AddMaxEquality(itv3, (0, itv2))
                        model.Add(itv4 >= itv3)
                        model.Add(itv4 <= int(ems_interval_time[i]))
                        model.Add(ems_itv == cd[0] + itv4 + 1)
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0], ems_itv,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    else:
                        j_sub_p_I_intervals = model.NewOptionalIntervalVar(ini[0],
                                                                           cd[0] + int(ems_interval_time[i]) + 1,
                                                                           mm_v,
                                                                           bool_sub_job_list[i][j][e][0],
                                                                           '%d_%d_I' % (i, j))  # 发车间隔时间变量
                    x_tt_intervals.append(j_sub_p_I_intervals)
            model.AddNoOverlap(x_tt_intervals)
    load_rate = []

    for i in range(len(job_data)):
        sub_load_rate = []
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                total_goods = 0
                for p in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][p] == 0:
                        total_goods += job_data[i][j][k][p] * zhuan_hua_EMS[i]
                    else:
                        total_goods += job_data[i][j][k][p]
                sub_load_rate.append(total_goods / rong_liang_EMS[i])
        load_rate.append(sub_load_rate)

    load_rate_index = []

    for i in range(len(load_rate)):
        sub_load_rate = sorted(enumerate(load_rate[i]), key=lambda x: x[1], reverse=True)
        sub_load_index = [ind for ind, _ in sub_load_rate]
        load_rate_index.append(sub_load_index)

    for i in range(len(load_rate_index)):
        if len(load_rate_index[i]) > 1:
            for k in range(len(load_rate_index[i]) - 1):
                model.Add(
                    job_p_list[i][0][load_rate_index[i][k]][0][0] < job_p_list[i][0][load_rate_index[i][k + 1]][0][0])

    # for i in range(len(job_p_list)):
    #     for j in range(len(job_p_list[i])):
    #         if len(job_p_list[i][j]) > 1:
    #             for k in range(len(job_p_list[i][j]) - 1):
    #                 model.Add(job_p_list[i][j][k][0][0] < job_p_list[i][j][k + 1][0][0])



    de_zz_delivery_count = [1] * len(rs_zz_delivery_count)
    de_ems_delivery_count = [1] * len(rs_ems_delivery_count)
    model.AddNoOverlap2D(x_intervals, y_intervals)
    model.AddCumulative(rs_c, de, int(10000 * box_flow_value * dis))  # 件箱库流量约束
    model.AddCumulative(rs_zz_delivery_count, de_zz_delivery_count, zz_delivery_count)  # 件箱库流量约束
    model.AddCumulative(rs_ems_delivery_count, de_ems_delivery_count, ems_delivery_count)  # 件箱库流量约束
    # # 优先级逻辑，待处理
    # for i in range(len(job_data) - 1):
    #     model.Add(bool_job_list[i] == 1).OnlyEnforceIf(bool_job_list[i + 1])

    # 优先级逻辑
    # car_first_start_time = []
    #
    # for i in range(len(job_p_list)):
    #     sub_car_first_start_time = []
    #     for j in range(len(job_p_list[i])):
    #         for k in range(len(job_p_list[i][j])):
    #             sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
    #     car_first_start_time.append(sub_car_first_start_time)
    #
    # for i in range(len(car_first_start_time) - 1):
    #     first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % i)
    #     next_first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % (i + 1))
    #     model.AddMinEquality(first_start_time, car_first_start_time[i])
    #     model.AddMinEquality(next_first_start_time, car_first_start_time[i + 1])
    #     model.Add(first_start_time <= next_first_start_time)

    priority_index = sorted(ems_priority)
    car_first_start_time = []
    for i in range(len(job_p_list)):
        sub_car_first_start_time = []
        for j in range(len(job_p_list[i])):
            for k in range(len(job_p_list[i][j])):
                sub_car_first_start_time.append(job_p_list[i][j][k][0][0])
        car_first_start_time.append(sub_car_first_start_time)

    left = 0
    for i in range(1, len(car_first_start_time)):
        if (priority_index[i] > priority_index[i - 1]):
            for j in range(left, i):
                first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % i)
                next_first_start_time = model.NewIntVar(0, 99999999, 'first_start_time_%d' % (i + 1))
                model.AddMinEquality(first_start_time, car_first_start_time[j])
                model.AddMinEquality(next_first_start_time, car_first_start_time[i])
                model.Add(first_start_time <= next_first_start_time)
            left = i

    # [model.Add(ems_c_occupy_s[i]==sum(ems_c_num_occupy[i])) for i in range(len(ems_c_occupy_s))]
    #
    # for i in range(len(ems_c_occupy)):
    #     model.Add(ems_c_occupy_s[i]>0).OnlyEnforceIf(ems_c_occupy[i])
    #     model.Add(ems_c_occupy_s[i]<=0).OnlyEnforceIf(ems_c_occupy[i].Not())
    #
    # if total_ems_cargo_num<=10 :
    #     model.Add(sum(ems_c_occupy)<=1)
    # if total_ems_cargo_num>10 and total_ems_cargo_num<=50 :
    #     model.Add(sum(ems_c_occupy)<=2)
    # if total_ems_cargo_num>=50 :
    #     model.Add(sum(ems_c_occupy)<=3)


    model.Maximize(total_bbb)  # 最大化排进去的车
    solver = cp_model.CpSolver()
    solver.parameters.num_search_workers = 8
    solver.parameters.max_time_in_seconds = t
    status1 = solver.Solve(model)



    # 得到最终的解
    solution_find = False

    if status1 == cp_model.OPTIMAL or status1 == cp_model.FEASIBLE:
        model.Add(total_bbb == round(solver.ObjectiveValue()))
        model.Minimize(sum(min_end_time))
        status2 = solver.Solve(model)
        if status2 == cp_model.OPTIMAL or status2 == cp_model.FEASIBLE:
            solution_find = True
            if status1 == cp_model.OPTIMAL and status2 == cp_model.OPTIMAL:
                logger.info("EMS时间窗模型求得最优解")
            elif (status1 == cp_model.FEASIBLE or status1 == cp_model.OPTIMAL) and (status2 == cp_model.FEASIBLE or status2 == cp_model.OPTIMAL):
                logger.info("EMS时间窗模型求得次优解")
            else:
                logger.info("EMS时间窗模型无解,程序结束")
                # exit()
    if solution_find == False:
        logger.error("EMS时间窗模型无解,程序结束")
        # exit()

    for i in range(len(job_data)):
        solu_x_sub = []
        for j in range(len(job_data[i])):
            u_solu_x_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    solution_x = []
                    if not solution_find:
                        solution_x.append(0)
                        solution_x.append(0)
                    else:
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][0]))
                        solution_x.append(solver.Value(job_p_list[i][j][g][k][1]))
                    so.append(solution_x)
                u_solu_x_sub.append(so)
            solu_x_sub.append(u_solu_x_sub)
        solution_x_total.append(solu_x_sub)

    for i in range(len(job_data)):
        solu_bool_sub = []
        for j in range(len(job_data[i])):
            u_solu_bool_sub = []
            for g in range(len(job_data[i][j])):
                so = []
                for k in range(len(job_data[i][j][g])):
                    if not solution_find:
                        so.append(0)
                    else:
                        so.append(solver.Value(bool_sub_job_list[i][j][g][k]))
                u_solu_bool_sub.append(so)
            solu_bool_sub.append(u_solu_bool_sub)
        solution_bool_sub_job.append(solu_bool_sub)

    for i in range(len(job_data)):
        solu_C_sub = []
        for j in range(len(job_data[i])):
            solu_C_sub_sub = []
            for e in range(len(job_data[i][j])):
                u_solu_C_sub_sub = []
                if len(job_data[i][j][e]) == 2:
                    so = []
                    c_index_list = []
                    for p in range(len(job_data[i][j][e])):
                        if job_type[i][j][e][p] == 1:
                            c_index_list.append(p)

                    for p in range(len(job_data[i][j][e])):
                        if job_type[i][j][e][p] == 0:
                            c_index_list.append(p)

                    for w in range(len(total_C_list[i][j][e][c_index_list[0]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[0]][w]))
                    so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                    for w in range(len(total_C_list[i][j][e][c_index_list[1]])):
                        if not solution_find:
                            so.append(0)
                        else:
                            so.append(solver.Value(total_C_list[i][j][e][c_index_list[1]][w]))
                    u_solu_C_sub_sub.append(so)

                else:
                    so = []
                    if job_type[i][j][e][0] == 1:
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        so = copy.deepcopy([so[random_ems_index[i]] for i in range(len(random_ems_index))])
                        so = so + [0] * len(c[0][0][1])
                        u_solu_C_sub_sub.append(so)
                    else:
                        for w in range(len(total_C_list[i][j][e][0])):
                            if not solution_find:
                                so.append(0)
                            else:
                                so.append(solver.Value(total_C_list[i][j][e][0][w]))
                        so = [0] * len(c[0][0][0]) + so
                        u_solu_C_sub_sub.append(so)

                solu_C_sub_sub.append(u_solu_C_sub_sub)
            solu_C_sub.append(solu_C_sub_sub)
        solution_bool_C.append(solu_C_sub)

    return solution_x_total, solution_bool_sub_job, solution_bool_C

def get_new_detail_id_arr(detail_id_arr,index_original_ems,index_original_zz):
    for id in detail_id_arr:
        if id:
            if id[0] == 0:
                id[1][0] = copy.deepcopy(index_original_zz.index(id[1][0]))
            if id[1] == 0:
                id[0][0] = copy.deepcopy(index_original_ems.index(id[0][0]))
    return detail_id_arr

class Logger(object):
    """
    Mock Interface
    Logger
    """

    @staticmethod
    def info(msg):
        print(f'[INFO] {Logger.date_str(datetime.now())} {msg}')

    @staticmethod
    def error(msg):
        print(f'[ERROR] {Logger.date_str(datetime.now())} {msg}')

    @staticmethod
    def date_str(date: datetime):
        return date.strftime('%Y-%m-%d %H:%M:%S') if date else None


def interval_Intersection(time_window, global_time,logger):
    '''
    自制的发车表时间是乱的，需要进行一个初步处理，让发车表时间从小到大排序，发车表的车辆也依次对应起来
    '''
    if global_time == []:
        return time_window

    global_time.sort(key=lambda x: (x[0]))

    newt = []
    i = 0
    j = 0
    while (i < len(time_window) and j < len(global_time)):
        if (time_window[i][1] < global_time[j][0]):
            i = i + 1
            continue
        if (time_window[i][0] > global_time[j][1]):
            j = j + 1
            continue
        newt.append([max(time_window[i][0], global_time[j][0]), min(time_window[i][1], global_time[j][1])])
        if (time_window[i][1] > global_time[j][1]):
            j = j + 1
        else:
            i = i + 1
    if (newt == []):
        logger.error("时间窗和工厂日历没有重合的工作时间!程序结束")
        exit()
    return newt


def time_process(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,insert_time,logger=Logger):
    '''
    直接使用时间戳时间可能超过求解器的允许的最大数值，因此需要对所有设计时间的参数进行归一化
    '''
    min_ems_begin_time = min(ems_begin_time) if ems_begin_time != [] else max_value
    min_ems_end_time = min(ems_end_time) if ems_end_time != [] else max_value
    min_zz_begin_time = min(min(zz_begin_time)) if zz_begin_time != [] else max_value
    min_zz_end_time = min(min(zz_end_time)) if zz_end_time != [] else max_value
    min_time_window = min(min(time_window)) if time_window != [] else max_value
    min_global_time = min(min(global_time)) if global_time != [] else max_value
    min_time = min(min_ems_begin_time,min_ems_end_time,min_zz_begin_time,min_zz_end_time,min_time_window,min_global_time,insert_time)

    ems_begin_time = [int(ems_begin_time[i] - min_time) for i in range(len(ems_begin_time))]
    ems_end_time = [int(ems_end_time[i] - min_time) for i in range(len(ems_end_time))]
    zz_begin_time = [[int(zz_begin_time[i][j] - min_time) for j in range(len(zz_begin_time[i]))] for i in
                     range(len(zz_begin_time))]
    zz_end_time = [[int(zz_end_time[i][j] - min_time) for j in range(len(zz_end_time[i]))] for i in
                   range(len(zz_end_time))]
    time_window = [[int(time_window[i][j] - min_time) for j in range(len(time_window[i]))] for i in
                   range(len(time_window))]
    global_time = [[int(global_time[i][j] - min_time) for j in range(len(global_time[i]))] for i in
                   range(len(global_time))]
    insert_time = int(insert_time-min_time)
    max_ems_begin_time = max(ems_begin_time) if ems_begin_time != [] else min_value
    max_ems_end_time = max(ems_end_time) if ems_end_time != [] else min_value
    max_zz_begin_time = max(max(zz_begin_time)) if zz_begin_time != [] else min_value
    max_zz_end_time = max(max(zz_end_time)) if zz_end_time != [] else min_value
    max_time_window = max(max(time_window)) if time_window != [] else min_value
    max_global_time = max(max(global_time)) if global_time != [] else min_value
    max_time = int(
        max(max_ems_begin_time, max_ems_end_time, max_zz_begin_time, max_zz_end_time, max_time_window, max_global_time,insert_time))

    if(insert_time>time_window[-1][-1]):
        logger.error("插单时间不在时间窗内！程序结束")
        exit()

    return ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time, min_time, max_time,insert_time

def time_process_no_insert(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,logger=Logger):

    min_ems_begin_time = min(ems_begin_time) if ems_begin_time != [] else max_value
    min_ems_end_time = min(ems_end_time) if ems_end_time != [] else max_value
    min_zz_begin_time = min(min(zz_begin_time)) if zz_begin_time != [] else max_value
    min_zz_end_time = min(min(zz_end_time)) if zz_end_time != [] else max_value
    min_time_window = min(min(time_window)) if time_window != [] else max_value
    min_global_time = min(min(global_time)) if global_time != [] else max_value
    min_time = min(min_ems_begin_time,min_ems_end_time,min_zz_begin_time,min_zz_end_time,min_time_window,min_global_time)

    ems_begin_time = [int(ems_begin_time[i] - min_time) for i in range(len(ems_begin_time))]
    ems_end_time = [int(ems_end_time[i] - min_time) for i in range(len(ems_end_time))]
    zz_begin_time = [[int(zz_begin_time[i][j] - min_time) for j in range(len(zz_begin_time[i]))] for i in
                     range(len(zz_begin_time))]
    zz_end_time = [[int(zz_end_time[i][j] - min_time) for j in range(len(zz_end_time[i]))] for i in
                   range(len(zz_end_time))]
    time_window = [[int(time_window[i][j] - min_time) for j in range(len(time_window[i]))] for i in
                   range(len(time_window))]
    global_time = [[int(global_time[i][j] - min_time) for j in range(len(global_time[i]))] for i in
                   range(len(global_time))]
    max_ems_begin_time = max(ems_begin_time) if ems_begin_time != [] else min_value
    max_ems_end_time = max(ems_end_time) if ems_end_time != [] else min_value
    max_zz_begin_time = max(max(zz_begin_time)) if zz_begin_time != [] else min_value
    max_zz_end_time = max(max(zz_end_time)) if zz_end_time != [] else min_value
    max_time_window = max(max(time_window)) if time_window != [] else min_value
    max_global_time = max(max(global_time)) if global_time != [] else min_value
    max_time = int(
        max(max_ems_begin_time, max_ems_end_time, max_zz_begin_time, max_zz_end_time, max_time_window, max_global_time))

    return ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time, min_time, max_time

def insert_time_process(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,deliver_plan_time,insert_time,logger):
    min_ems_begin_time = min(ems_begin_time)  if ems_begin_time != [] else max_value
    min_ems_end_time = min(ems_end_time)  if ems_end_time != [] else max_value
    min_zz_begin_time = min(min(zz_begin_time))  if zz_begin_time != [] else max_value
    min_zz_end_time = min(min(zz_end_time))  if zz_end_time != [] else max_value
    min_time_window = min(min(time_window))  if time_window != [] else max_value
    min_global_time = min(min(global_time))  if global_time != [] else max_value
    min_deliver_plan_time = min(min(min(deliver_plan_time)))  if deliver_plan_time != [] else max_value
    min_time = min(min_ems_begin_time,min_ems_end_time,min_zz_begin_time,min_zz_end_time,min_time_window,min_global_time,min_deliver_plan_time,insert_time)

    ems_begin_time = [int(ems_begin_time[i] - min_time) for i in range(len(ems_begin_time))]
    ems_end_time = [int(ems_end_time[i] - min_time) for i in range(len(ems_end_time))]
    zz_begin_time = [[int(zz_begin_time[i][j] - min_time) for j in range(len(zz_begin_time[i]))] for i in
                     range(len(zz_begin_time))]
    zz_end_time = [[int(zz_end_time[i][j] - min_time) for j in range(len(zz_end_time[i]))] for i in
                   range(len(zz_end_time))]
    time_window = [[int(time_window[i][j] - min_time) for j in range(len(time_window[i]))] for i in
                   range(len(time_window))]
    global_time = [[int(global_time[i][j] - min_time) for j in range(len(global_time[i]))] for i in
                   range(len(global_time))]
    deliver_plan_time = [[[int(deliver_plan_time[i][j][k] - min_time) for k in range(len(deliver_plan_time[i][j]))] for j in range(len(deliver_plan_time[i]))] for i in
                   range(len(deliver_plan_time))]
    insert_time = int(insert_time-min_time)
    max_ems_begin_time = max(ems_begin_time) if ems_begin_time != [] else min_value
    max_ems_end_time = max(ems_end_time) if ems_end_time != [] else min_value
    max_zz_begin_time = max(max(zz_begin_time)) if zz_begin_time != [] else min_value
    max_zz_end_time = max(max(zz_end_time)) if zz_end_time != [] else min_value
    max_time_window = max(max(time_window)) if time_window != [] else min_value
    max_global_time = max(max(global_time)) if global_time != [] else min_value
    max_deliver_plan_time = max(max(max(deliver_plan_time))) if deliver_plan_time != [] else min_value
    max_time = int(
        max(max_ems_begin_time, max_ems_end_time, max_zz_begin_time, max_zz_end_time, max_time_window, max_global_time,max_deliver_plan_time,insert_time))

    if(insert_time>time_window[-1][-1]):
        logger.error("插单时间不在时间窗内！程序结束")
        exit()
    return ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time, deliver_plan_time,min_time, max_time,insert_time


def repair_time(end_solution_x_total, end_sxt, zz_r, min_time):
    for i in range(len(end_solution_x_total)):
        for j in range(len(end_solution_x_total[i])):
            for k in range(len(end_solution_x_total[i][j])):
                for l in range(len(end_solution_x_total[i][j][k])):
                    for m in range(len(end_solution_x_total[i][j][k][l])):
                        end_solution_x_total[i][j][k][l][m] = end_solution_x_total[i][j][k][l][m] + min_time

    for i in range(len(end_sxt)):
        for j in range(len(end_sxt[i])):
            for k in range(len(end_sxt[i][j])):
                for l in range(len(end_sxt[i][j][k])):
                    for m in range(len(end_sxt[i][j][k][l])):
                        end_sxt[i][j][k][l][m] = end_sxt[i][j][k][l][m] + min_time

    for i in range(len(zz_r)):
        for j in range(len(zz_r[i])):
            for k in range(len(zz_r[i][j])):
                for l in range(len(zz_r[i][j][k])):
                    for m in range(len(zz_r[i][j][k][l])):
                        zz_r[i][j][k][l][m] = zz_r[i][j][k][l][m] + min_time
    return end_solution_x_total, end_sxt, zz_r

def update_insert_time(time_window,no_work_time_re,insert_time):
    for i,tw in enumerate(time_window) :
        if(tw[0]<=insert_time and tw[1]>=insert_time):
            insert_time = insert_time - no_work_time_re[i]
            break
    return  insert_time

def insert_fun(ems_goods_num, ems_begin_time, ems_end_time, ems_job_type, c, V_j, ems_goods, zz_goods_num,
                    zz_begin_time,
                    zz_end_time, zz_job_type, zz_goods, s_c, V_se_j, fu_dong_EMS, fu_dong_zz, rong_liang_EMS,
                    rong_liang_zz,
                    zhuan_hua_EMS, zhuan_hua_zz, a_c, p_num, time_window, dis, zz_car_num, t1, t2, EMS_interval_time,
                    zz_interval_time, ems_priority, zz_priority, deliver_plan_time, detail_port_num, detail_id_arr,
                    insert_time, global_time, box_flow_value, ems_delivery_count, zz_delivery_count,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2, ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger=Logger):
    '''
    主函数，直接用这个就行
    :param ems_goods_num:EMS的货物量，第一个维度为厂家，第二个维度为订单详情
    :param ems_begin_time:对应于EMS厂家的最早开始时间，只有一个维度
    :param ems_end_time:对应于EMS厂家的最晚结束时间，只有一个维度
    :param ems_job_type:对应于EMS货物的形态，1是件箱，0是栈板，第一个维度为厂家，第二个维度为订单详情
    :param c:对应于EMS的可用通道，第一个为厂家，第二个维度为订单详情，第三个维度为货物类别，不同类别对应于不同的通道
    :param V_j:输入到EMS求解的速度参数
    :param ems_goods:EMS的货物数量
    :param zz_goods_num:自制的货物量，这回既有件箱又有栈板，第一个维度为厂家，第二个维度为订单详情
    :param zz_begin_time:对应于自制厂家的最早开始时间，只有一个维度
    :param zz_end_time:对应于自制厂家的最晚结束时间，只有一个维度
    :param zz_job_type:对应于自制货物的形态，1是件箱，0是栈板，第一个维度为厂家，第二个维度为订单详情
    :param zz_goods:自制的货物数量
    :param s_c:对应于自制的可用通道，第一个为厂家，第二个维度为订单详情，第三个维度为货物类别，不同类别对应于不同的通道
    :param V_se_j:输入到自制求解的速度参数，V_se_j[0]和V_se_j[1]与V_j[0]和V_j[2]数值上是一样的
    :param fu_dong_EMS:对应于厂家的浮动系数，只有一个维度(EMS)
    :param fu_dong_zz:对应于厂家的浮动系数，只有一个维度(自制)
    :param rong_liang_EMS:对应于厂家的车辆容量，只有一个维度(EMS)
    :param rong_liang_zz:对应于厂家的车辆容量，只有一个维度(自制)
    :param zhuan_hua_EMS:对应于厂家的转换系数，只有一个维度(EMS)
    :param zhuan_hua_zz:对应于厂家的转换系数，只有一个维度(自制)
    :param a_c:栈板的总通道数量
    :param p_num:EMS的件箱总通道数量
    :param time_window:工作时间窗
    :param dis:打折系数
    :param zz_car_num:自制车的数量
    :param t1:EMS求解时间
    :param t2:自制求解时间
    :param EMS_interval_time:EMS发车间隔时间
    :param zz_interval_time:自制发车间隔时间
    :return:end_solution_x_total:EMS所有子任务的开始处理时间和处理结束时间，单位为分钟
     solution_bool_sub_job:该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理(EMS)
     solution_bool_C:该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用(EMS)
     end_sxt:自制所有子任务的开始处理时间和处理结束时间，单位为分钟
     sbsj:该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理(自制)
     sbc:该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用(自制)
     car:每辆车装载的货物量(EMS在前，自制在后，件箱和栈板的数量)
     job_re:记录每辆车装载的货物编号(对应于car，也对应于good_nums)
     job_total:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
     job_type_total:EMS货物形态 0可代表栈板，1代表件箱
     job_se_total:自制任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量
     job_se_type_total:自制货物形态 0可代表栈板，1代表件箱
     goods_num:每辆车装载的货物量(EMS在前，自制在后，对应于箱内的数量，不是件箱栈板的数量)
     total_d_num:每辆车订单详情对应的件箱栈板数量[a,b]，a对应件箱的数量，b对应栈板的数量(EMS在前，自制在后)
     total_d_goods:每辆车订单详情对应的货物的数量[a,b]，a对应件箱位置的货物数量，b对应栈板位置的货物数量(EMS在前，自制在后)
     zz_r:自制的真实时间
     no_car_re：缺车的订单详情
    '''

    # deliver_plan_time, detail_port_num, detail_id_arr = remove_du(deliver_plan_time, detail_port_num, detail_id_arr)
    # 主要处理重排的函数
    random_ems_index,random_zz_index = get_random_index(p_num,s_c)

    ems_end_time = get_ems_end_time(time_window,ems_end_time)
    detail_id_arr = [copy.deepcopy(detail_id_arr[i]) for i in range(len(detail_id_arr))]

    ems_begin_time, zz_begin_time = get_start_time(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time,
                                                   insert_time)

    ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,deliver_plan_time, min_time, max_time,insert_time = insert_time_process(
        ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,deliver_plan_time,insert_time,logger)

    # if insert_time is None:
    #     current_time = datetime.now()
    #
    #     insert_time = current_time.hour * 60 + current_time.minute  # 得到当前时刻的分钟数

    ems_time_lock, ems_port_lock, zz_time_lock, zz_port_lock, zz_d1, ems_begin_time = get_insert_start_time(insert_time,
                                                                                                            deliver_plan_time,
                                                                                                            detail_port_num,
                                                                                                            detail_id_arr,
                                                                                                            ems_begin_time,
                                                                                                            EMS_interval_time,
                                                                                                            zz_interval_time)  # 得到被锁定的时间和需要限定的开始时间

    ems_goods_num, ems_begin_time, ems_end_time, ems_job_type, ems_goods, zz_goods_num, \
    zz_begin_time, zz_end_time, zz_job_type, zz_goods, s_c, fu_dong_EMS, fu_dong_zz, \
    rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS, zhuan_hua_zz, EMS_interval_time, \
    zz_interval_time, index_original_ems, index_original_zz, zz_car_num, V_j, V_se_j,portEmsLpnNum3, portEmsLpnNum2, portSelfLpnNum2 = priority_process(ems_priority,
                                                                                            zz_priority,
                                                                                            ems_goods_num,
                                                                                            ems_begin_time,
                                                                                            ems_end_time,
                                                                                            ems_job_type,
                                                                                            ems_goods,
                                                                                            zz_goods_num,
                                                                                            zz_begin_time,
                                                                                            zz_end_time,
                                                                                            zz_job_type,
                                                                                            zz_goods,
                                                                                            s_c,
                                                                                            fu_dong_EMS,
                                                                                            fu_dong_zz,
                                                                                            rong_liang_EMS,
                                                                                            rong_liang_zz,
                                                                                            zhuan_hua_EMS,
                                                                                            zhuan_hua_zz,
                                                                                            EMS_interval_time,
                                                                                            zz_interval_time,
                                                                                            zz_car_num, V_j,
                                                                                            V_se_j,
                                                                                            box_flow_value,p_num, portEmsLpnNum3, portEmsLpnNum2, portSelfLpnNum2
                                                                                            )  # 优先级重排
    detail_id_arr = [copy.deepcopy(detail_id_arr[i]) for i in range(len(detail_id_arr))]
    detail_id_arr = get_new_detail_id_arr(detail_id_arr,index_original_ems,index_original_zz)

    # print("ems_goods_num: ", ems_goods_num)
    # print("ems_job_type: ", ems_job_type)
    # print("fu_dong_EMS: ", fu_dong_EMS)
    # print("rong_liang_EMS: ", rong_liang_EMS)
    # print("zhuan_hua_EMS: ", zhuan_hua_EMS)

    zz_begin_time, zz_end_time, zz_car_num = get_ini_zz_time_car(zz_begin_time, zz_end_time,
                                                                 zz_car_num)  # 自制的发车表时间是乱的，需要进行一个初步处理，让发车表时间从小到大排序，发车表的车辆也依次对应起来




    time_window = interval_Intersection(time_window, global_time,logger)
    time_window = time_window_combie(time_window)

    if insert_time != None:
        zz_car_num,zz_begin_time, zz_end_time  = insert_sort_zz_time(zz_begin_time, zz_end_time,zz_car_num,time_window,insert_time)
    else:
        zz_car_num, zz_begin_time, zz_end_time = sort_zz_time(zz_begin_time, zz_end_time, zz_car_num,time_window)

    ems_begin_time, ems_end_time = start_end_time_process(ems_begin_time, ems_end_time,
                                                          time_window,logger)  # 由于EMS给出的开始时间和deadline可能不在时间窗的范围内，因此这里做出处理，若不在范围内，就以时间窗的最早开始时间和最晚结束时间作为EMS厂家的开始时间和deadline

    ems_n_start_time, ems_n_d_list, no_work_time_re, work_time_list, interval_time = time_window_process(time_window, ems_begin_time,
                                                                                          ems_end_time)  # 时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    # 将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    # 这个函数处理了EMS的开始时间和结束时间

    # if (is_splitting_car)
    # job_total, job_type_total, job_re_ems, goods_num_ems, ems_car_d_num, ems_car_d_type, ems_car_d_goods_num, _, _, order_sequence = load_without_splitting_car(ems_goods_num,ems_job_type,ems_goods,ems_detail_add_date)
    # job_se_total, job_se_type_total, zz_job_re, zz_goods_num_new, zz_car_d_num, zz_car_d_type, zz_car_d_goods_num, no_car_re, no_job_data_re,order_sequence = load_without_splitting_car(zz_goods_num,zz_job_type,zz_goods,zz_detail_add_date)

    job_total, job_type_total, job_re_ems, goods_num_ems, ems_car_d_num, ems_car_d_type, ems_car_d_goods_num = load_fun_3(
        ems_goods_num, ems_job_type, len(ems_goods_num), fu_dong_EMS, rong_liang_EMS, zhuan_hua_EMS,
        ems_goods)  # EMS装车模型

    job_se_total, job_se_type_total, zz_job_re, zz_goods_num_new, zz_car_d_num, zz_car_d_type, zz_car_d_goods_num, no_car_re, no_job_data_re = load_se(
        zz_goods_num, zz_job_type, rong_liang_zz, zhuan_hua_zz, zz_goods, zz_car_num,t1,logger)  # 自制装车模型




    zz_begin_time, zz_end_time, zz_car_num = remove_lock_time(deliver_plan_time, detail_port_num, detail_id_arr,
                                                              insert_time, zz_begin_time, zz_end_time, zz_car_num, c,
                                                              s_c, copy.deepcopy(V_j), copy.deepcopy(V_se_j),
                                                              zz_interval_time, job_se_total, job_se_type_total, dis)

    job_se_total, job_se_type_total, zz_job_re, zz_goods_num_new, zz_car_d_num, zz_car_d_type, zz_car_d_goods_num, no_car_re_1,no_job_data_re1, zz_begin_time, zz_end_time, zz_car_num = zz_process_1(
        job_se_total, job_se_type_total, zz_job_re, zz_goods_num_new, zz_car_d_num, zz_car_d_type, zz_car_d_goods_num,
        zz_car_num, zz_begin_time, zz_end_time)

    car_time_before = insert_get_se_car_to_time_before(job_se_total, zz_begin_time, zz_end_time,
                                                zz_car_num,insert_time)  # 该函数用于得到还未经time_window_process_se函数处理过的自制发车时间，主要作用就是给排的自制车分配发车的开始时间和结束时间，然后方便get_end_zz_time函数的使用

    zz_n_start_time, zz_n_d_list = time_window_process_se(time_window, zz_begin_time,
                                                          zz_end_time,insert_time)  # 时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    # 将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    # 这个函数处理了自制发车表的开始时间和结束时间

    insert_time = update_insert_time(time_window,no_work_time_re,insert_time)

    car_time = insert_get_se_car_to_time(job_se_total, zz_n_start_time, zz_n_d_list,
                                  zz_car_num,insert_time)  # 该函数就是把处理后的自制发车表时间分配给排的自制车，在功能的实现上和get_se_car_to_time_before是一样的，但是得到的时间是经过time_window_process_se处理过的

    sxt, sbsj, sbc, sbc_n = insert_se_solve(job_se_total, job_se_type_total, zz_n_start_time, copy.deepcopy(V_se_j),
                                            s_c, a_c,
                                            dis, car_time,
                                            copy.deepcopy(V_j), t2, zz_interval_time, c, ems_time_lock, ems_port_lock,
                                            zz_time_lock, zz_port_lock, zz_d1, index_original_zz, insert_time,
                                            rong_liang_zz, zhuan_hua_zz, box_flow_value, zz_delivery_count,
                                            ems_delivery_count,max_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger)  # 自制时间窗

    solution_x_total, solution_bool_sub_job, solution_bool_C = insert_solve(job_total, ems_n_d_list, job_type_total,
                                                                            ems_n_start_time,
                                                                            sxt, sbsj, sbc_n, job_se_type_total,
                                                                            copy.deepcopy(V_j), s_c,c, p_num,
                                                                            a_c, dis, t1, EMS_interval_time,
                                                                            ems_time_lock, ems_port_lock, zz_time_lock,
                                                                            zz_port_lock, rong_liang_EMS, zhuan_hua_EMS,
                                                                            box_flow_value, zz_delivery_count,
                                                                            ems_delivery_count,ems_priority,max_time,work_time_list, interval_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger)  # EMS时间窗

    end_solution_x_total = get_end_time(solution_x_total, solution_bool_sub_job, no_work_time_re,
                                        work_time_list)  # 该函数用于得到加入不工作时间后最终的时间窗结果

    end_sxt = get_end_time(sxt, sbsj, no_work_time_re, work_time_list)  # # 该函数用于得到加入不工作时间后最终的时间窗结果

    zz_r = copy.deepcopy(end_sxt)  # 保存自制的真实作业时间

    end_sxt = get_end_zz_time(car_time_before, end_sxt, sbsj)  # 该函数用于将自制的真实工作时间转换为自制的发车表时间

    car = job_total + job_se_total  # 得到最终的装车模型的输出（EMS在前，自制在后）

    goods_num = goods_num_ems + zz_goods_num_new  # 得到最终的货物内部数量的输出

    solution_bool_C = solution_c_ems_process(end_solution_x_total, job_total, job_type_total, solution_bool_sub_job,
                                             solution_bool_C, job_re_ems, copy.deepcopy(V_j), dis, c,
                                             copy.deepcopy(V_se_j))  # 通道资源过多的处理



    sbc = solution_c_zz_process(zz_r, job_se_total, job_se_type_total, sbsj, sbc, zz_job_re, copy.deepcopy(V_se_j),
                                dis, c, copy.deepcopy(V_se_j))  # 通道资源过多的处理
    # 对自制下标的处理，方便EMS和自制下标的合并
    for i in range(len(zz_job_re)):
        for j in range(len(zz_job_re[i])):
            for k in range(len(zz_job_re[i][j])):
                for p in range(len(zz_job_re[i][j][k])):
                    zz_job_re[i][j][k][p][0] += len(job_re_ems)

    # 将自制和EMS的下标合并
    job_re = job_re_ems + zz_job_re

    # 对下标进行最终的处理，得到输出需要的下标
    job_re_end = process_job_re(job_re)

    # 对货物数量和货物内部数量的处理，得到需要的输出
    total_d_num, total_d_goods = d_process(job_re, job_re_end, ems_car_d_num, ems_car_d_type, ems_car_d_goods_num,
                                           zz_car_d_num, zz_car_d_type, zz_car_d_goods_num)
    # 下标的还原
    for i in range(len(job_re_end)):
        for j in range(len(job_re_end[i])):
            for k in range(len(job_re_end[i][j])):
                for p in range(len(job_re_end[i][j][k])):
                    if i < len(job_re_ems):
                        job_re_end[i][j][k][p][0] = index_original_ems[i]
                    else:
                        f = job_re_end[i][j][k][p][0]
                        job_re_end[i][j][k][p][0] = index_original_zz[f - len(job_re_ems)] + len(job_re_ems)

    if bool(no_car_re):
        for i in range(len(no_car_re)):
            f = no_car_re[i][0]
            no_car_re[i][0] = index_original_zz[f] + len(job_re_ems)

    if bool(no_car_re_1):
        for i in range(len(no_car_re_1)):
            f = no_car_re_1[i][0]
            no_car_re_1[i][0] = index_original_zz[f] + len(job_re_ems)

    no_car_re = no_car_re + no_car_re_1
    no_job_data_re = no_job_data_re + no_job_data_re1
    new_no_job_data_re = []
    new_no_car_re = []
    re_s = set()
    for i in range(len(no_car_re)):
        if tuple(no_car_re[i]) not in re_s:
            re_s.add(tuple(no_car_re[i]))
            new_no_car_re.append(copy.deepcopy(no_car_re[i]))
            new_no_job_data_re.append(copy.deepcopy(no_job_data_re[i]))
        else:
            new_no_job_data_re[new_no_car_re.index(no_car_re[i])][0] += copy.deepcopy(no_job_data_re[i][0])
            new_no_job_data_re[new_no_car_re.index(no_car_re[i])][1] += copy.deepcopy(no_job_data_re[i][1])

    end_solution_x_total, end_sxt, zz_r = repair_time(end_solution_x_total, end_sxt, zz_r, min_time)

    return end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re_end, job_total, \
           job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_r, new_no_car_re,new_no_job_data_re

def time_window_combie(time_window):
    if len(time_window)<2:
        return time_window
    new_time_window = []
    start = 0
    for end in range(1,len(time_window)):
        if time_window[end][0] == time_window[end-1][1] and end!=len(time_window)-1:
            continue
        if time_window[end][0] == time_window[end - 1][1] and end == len(time_window) - 1:
            new_time_window.append([time_window[start][0], time_window[end][1]])
        if time_window[end][0] != time_window[end - 1][1] and end != len(time_window) - 1:
            new_time_window.append([time_window[start][0],time_window[end-1][1]])
            start = end
        if time_window[end][0] != time_window[end - 1][1] and end == len(time_window) - 1:
            new_time_window.append([time_window[start][0],time_window[end-1][1]])
            new_time_window.append([time_window[end][0],time_window[end][1]])
    return new_time_window

def get_start_time(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time,insert_time):

    new_ems_begin_time = []
    new_zz_begin_time = []

    for i in range(len(ems_begin_time)):
        if insert_time >=ems_begin_time[i] and insert_time <= ems_end_time[i]:
            new_ems_begin_time.append(insert_time)
        elif insert_time <ems_begin_time[i]:
            new_ems_begin_time.append(ems_begin_time[i])
        else:
            new_ems_begin_time.append(ems_end_time[i])

    for i in range(len(zz_begin_time)):
        sub_new_zz_begin_time = []
        for j in range(len(zz_begin_time[i])):
            if insert_time >=zz_begin_time[i][j]  and insert_time <= zz_end_time[i][j] :
                sub_new_zz_begin_time.append(insert_time)
            elif insert_time < zz_begin_time[i][j]:
                sub_new_zz_begin_time.append(zz_begin_time[i][j])
            else:
                sub_new_zz_begin_time.append(zz_end_time[i][j])
        new_zz_begin_time.append(sub_new_zz_begin_time)
    return new_ems_begin_time, new_zz_begin_time

def get_random_index(p_num,s_c):
    #c:自制通道
    #c:ems通道

    random_ems_index = [i for i in range(p_num)]
    random.shuffle(random_ems_index)

    if s_c:
        num_zz_index = max([len(s_c[i][0][0])*s_c[i][0][0][0]//2 for i in range(len(s_c))])
    else:
        num_zz_index = 0
    random_zz_index =  [i for i in range(num_zz_index)]
    random.shuffle(random_zz_index)

    return random_ems_index,random_zz_index

def get_zz_cargo_num(job_data,job_type,c):
    total_zz_cargo_num = []
    total_ems_cargo_num = []

    for i in range(len(job_data)):
        sub_total_zz_cargo_num = 0
        sub_total_ems_cargo_num = 0
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                for e in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][e] == 1:
                        if c[i][0][0][0] == 1:
                            sub_total_zz_cargo_num += job_data[i][j][k][e]
                        else:
                            sub_total_ems_cargo_num += job_data[i][j][k][e]

        total_zz_cargo_num.append(sub_total_zz_cargo_num)
        total_ems_cargo_num.append(sub_total_ems_cargo_num)


    return total_zz_cargo_num,total_ems_cargo_num

def get_ems_cargo_num(job_data,job_type):
    total_ems_cargo_num = []

    for i in range(len(job_data)):
        sub_total_ems_cargo_num = 0
        for j in range(len(job_data[i])):
            for k in range(len(job_data[i][j])):
                for e in range(len(job_data[i][j][k])):
                    if job_type[i][j][k][e] == 1:
                        sub_total_ems_cargo_num += job_data[i][j][k][e]
        total_ems_cargo_num.append(sub_total_ems_cargo_num)


    return total_ems_cargo_num

def walkthrough_fun(ems_goods_num, ems_begin_time, ems_end_time, ems_job_type, c, V_j, ems_goods, zz_goods_num, zz_begin_time,
             zz_end_time, zz_job_type, zz_goods, s_c, V_se_j, fu_dong_EMS, fu_dong_zz, rong_liang_EMS, rong_liang_zz,
             zhuan_hua_EMS, zhuan_hua_zz, a_c, p_num, time_window, dis, zz_car_num, t1, t2, EMS_interval_time,
             zz_interval_time, ems_priority, zz_priority, global_time, box_flow_value, ems_delivery_count,
             zz_delivery_count,insert_time,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger):
    # logger.info("jiasod")
    # logger.error("asjdoaisdjo")
    '''
    主函数，直接用这个就行
    :param ems_goods_num:EMS的货物量；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    :param ems_begin_time:对应于EMS厂家的最早开始时间，只有一个维度
    :param ems_end_time:对应于EMS厂家的最晚结束时间，只有一个维度
    :param ems_job_type:对应于EMS货物的形态，1是件箱，0是栈板，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，订单类型
    :param c:对应于EMS的可用通道；维度1，维度2，维度3，维度4 = 厂家，订单，通道类型，通道 ；通道类型中前一个维度都是件箱的，后一个维度都是栈板的，如c = [[[[1, 1, 1, 1], [1, 1]]]]中[1, 1, 1, 1]表示件箱可用的通道，[1,1]表示栈板可用的通道
    :param V_j:输入到EMS求解的速度参数,单位:数量/秒，[栈板速度，件箱速度，自制速度]
    :param ems_goods:EMS的货物数量；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    :param zz_goods_num:自制的货物量，其中既有件箱又有栈板，维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物量
    :param zz_begin_time:对应于自制厂家每辆车的最早开始时间， 维度1，维度2=  厂家，时间
    :param zz_end_time:对应于自制厂家每辆车的最晚结束时间，维度1，维度2=  厂家，时间
    :param zz_job_type:对应于自制货物的形态，1是件箱，0是栈板，第一个维度为厂家，第二个维度为订单详情
    :param zz_goods:自制的货物数量；维度1，维度2，维度3，维度4 =  厂家，订单，订单详情，货物数量
    :param s_c:对应于自制的可用通道；维度1，维度2，维度3 =  厂家，订单，货物类型，通道类型和数量；[0,1]表示1楼，[1,0]表示-1楼； 第三个维度前件箱，后栈板；如 s_c = [[[[1, 0, 1, 0], [1, 1, 1]]], [[[0, 1], [1, 1, 1]]]]表示第一个厂家安排了负1楼件箱通道2个,栈板通道3个;第二个厂家安排了1楼件箱通道1个,栈板通道3个
    :param V_se_j:输入到自制求解的速度参数，单位:数量/秒，[栈板速度，自制速度，件箱速度]
    :param fu_dong_EMS:对应于厂家的浮动系数，只有一个维度(EMS)
    :param fu_dong_zz:对应于厂家的浮动系数，只有一个维度(自制)
    :param rong_liang_EMS:对应于厂家的车辆容量，只有一个维度(EMS)
    :param rong_liang_zz:对应于厂家的车辆容量，只有一个维度(自制)
    :param zhuan_hua_EMS:对应于厂家的转换系数，只有一个维度(EMS)
    :param zhuan_hua_zz:对应于厂家的转换系数，只有一个维度(自制)
    :param a_c:栈板的总通道数量
    :param p_num:EMS的件箱总通道数量
    :param time_window:工作时间窗；维度1，维度2 =  某个时间间隔，时间
    :param dis:打折系数
    :param zz_car_num:自制车的数量
    :param t1:EMS求解时间
    :param t2:自制求解时间
    :param EMS_interval_time:EMS发车间隔时间
    :param zz_interval_time:自制发车间隔时间
    :return:end_solution_x_total:EMS所有子任务的开始处理时间和处理结束时间，单位为分钟
     solution_bool_sub_job:该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理(EMS)
     solution_bool_C:该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用(EMS)
     end_sxt:自制所有子任务的开始处理时间和处理结束时间，单位为分钟
     sbsj:该项对应某一个子任务是否被处理，若为1则被处理，若为0则没被处理(自制)
     sbc:该项对应子任务的通道使用情况，其中为1则该通道被使用，为0则没被使用(自制)
     car:每辆车装载的货物量(EMS在前，自制在后，件箱和栈板的数量)
     job_re:记录每辆车装载的货物编号(对应于car，也对应于good_nums)
     job_total:EMS任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量,同时任务的优先级默认从高到低依次排列
     job_type_total:EMS货物形态 0可代表栈板，1代表件箱
     job_se_total:自制任务的具体信息，即货物数量，该项包含n个任务和各个任务对应的子任务的货物数量
     job_se_type_total:自制货物形态 0可代表栈板，1代表件箱
     goods_num:每辆车装载的货物量(EMS在前，自制在后，对应于箱内的数量，不是件箱栈板的数量)
     total_d_num:每辆车订单详情对应的件箱栈板数量[a,b]，a对应件箱的数量，b对应栈板的数量(EMS在前，自制在后)
     total_d_goods:每辆车订单详情对应的货物的数量[a,b]，a对应件箱位置的货物数量，b对应栈板位置的货物数量(EMS在前，自制在后)
     zz_r:自制的真实时间
     no_car_re：缺车的订单详情
     no_job_data_re: 被丢弃的车中的货物，前件箱，后栈板
    '''

    random_ems_index,random_zz_index = get_random_index(p_num,s_c)
    ems_end_time = get_ems_end_time(time_window,ems_end_time) #EMS跨天预处理
    if insert_time!= None:
        ems_begin_time, zz_begin_time = get_start_time(ems_begin_time, ems_end_time, zz_begin_time, zz_end_time,insert_time)
        ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time, min_time, max_time,insert_time = time_process(
            ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,insert_time,logger=Logger) #时间戳归一化预处理
    else:
        ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time, min_time, max_time = time_process_no_insert(
            ems_begin_time, ems_end_time, zz_begin_time, zz_end_time, time_window, global_time,logger=Logger) #时间戳归一化预处理

    ems_goods_num, ems_begin_time, ems_end_time, ems_job_type, ems_goods, zz_goods_num, \
    zz_begin_time, zz_end_time, zz_job_type, zz_goods, s_c, fu_dong_EMS, fu_dong_zz, \
    rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS, zhuan_hua_zz, EMS_interval_time, \
    zz_interval_time, index_original_ems, index_original_zz, zz_car_num, V_j, V_se_j,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2 = priority_process(ems_priority,
                                                                                                        zz_priority,
                                                                                                        ems_goods_num,
                                                                                                        ems_begin_time,
                                                                                                        ems_end_time,
                                                                                                        ems_job_type,
                                                                                                        ems_goods,
                                                                                                        zz_goods_num,
                                                                                                        zz_begin_time,
                                                                                                        zz_end_time,
                                                                                                        zz_job_type,
                                                                                                        zz_goods,
                                                                                                        s_c,
                                                                                                        fu_dong_EMS,
                                                                                                        fu_dong_zz,
                                                                                                        rong_liang_EMS,
                                                                                                        rong_liang_zz,
                                                                                                        zhuan_hua_EMS,
                                                                                                        zhuan_hua_zz,
                                                                                                        EMS_interval_time,
                                                                                                        zz_interval_time,
                                                                                                        zz_car_num, V_j,
                                                                                                        V_se_j,
                                                                                                        box_flow_value,p_num,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2) #厂家优先级预处理

    # print("ems_job_type: ", ems_job_type)

    zz_begin_time, zz_end_time, zz_car_num = get_ini_zz_time_car(zz_begin_time, zz_end_time,
                                                                 zz_car_num)  # 自制发车表排序预处理，自制的发车表时间是乱的，需要进行一个初步处理，让发车表时间从小到大排序，发车表的车辆也依次对应起来

    time_window = interval_Intersection(time_window, global_time,logger) #时间窗合并
    time_window = time_window_combie(time_window)

    if insert_time != None:
        zz_car_num,zz_begin_time, zz_end_time  = insert_sort_zz_time(zz_begin_time, zz_end_time,zz_car_num,time_window,insert_time) #自制车辆优先级预处理
    else:
        zz_car_num, zz_begin_time, zz_end_time = sort_zz_time(zz_begin_time, zz_end_time, zz_car_num,time_window) #自制车辆优先级预处理

    ems_begin_time, ems_end_time = start_end_time_process(ems_begin_time, ems_end_time,
                                                          time_window,logger)  # 由于EMS给出的开始时间和deadline可能不在时间窗的范围内，因此这里做出处理，若不在范围内，就以时间窗的最早开始时间和最晚结束时间作为EMS厂家的开始时间和deadline

    ems_n_start_time, ems_n_d_list, no_work_time_re, work_time_list, interval_time= time_window_process(time_window, ems_begin_time,
                                                                                          ems_end_time)  # 时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    # 将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    # 这个函数处理了EMS的开始时间和结束时间

    job_total, job_type_total, job_re_ems, goods_num_ems, ems_car_d_num, ems_car_d_type, ems_car_d_goods_num = load_fun_3(
        ems_goods_num, ems_job_type, len(ems_goods_num), fu_dong_EMS, rong_liang_EMS, zhuan_hua_EMS,
        ems_goods)  # EMS装车模型

    job_se_total, job_se_type_total, zz_job_re, zz_goods_num_new, zz_car_d_num, zz_car_d_type, zz_car_d_goods_num, no_car_re, no_job_data_re = load_se(
        zz_goods_num, zz_job_type, rong_liang_zz, zhuan_hua_zz, zz_goods, zz_car_num,t1,logger)  # 自制装车模型


    car_time_before = get_se_car_to_time_before(job_se_total, zz_begin_time, zz_end_time,
                                                zz_car_num)  # 该函数用于得到还未经time_window_process_se函数处理过的自制发车时间，主要作用就是给排的自制车分配发车的开始时间和结束时间，然后方便get_end_zz_time函数的使用


    zz_n_start_time, zz_n_d_list = time_window_process_se(time_window, zz_begin_time,
                                                          zz_end_time)  # 时间窗的时间可能不是连续的，我们需要将不连续的时间去掉，使其变的连续，方便时间窗的计算，就像这样[[540, 740],[740, 940],[1140, 1340]] -> [[540, 740],[740, 940],[940, 1140]]
    # 将时间向前移，在那个需要移动的时间窗范围内的时间也需要移动，在时间窗模型计算完后，再把解进行还原
    # 这个函数处理了自制发车表的开始时间和结束时间

    car_time = get_se_car_to_time(job_se_total, zz_n_start_time, zz_n_d_list,
                                  zz_car_num)  # 该函数就是把处理后的自制发车表时间分配给排的自制车，在功能的实现上和get_se_car_to_time_before是一样的，但是得到的时间是经过time_window_process_se处理过的

    sxt, sbsj, sbc, sbc_n = se_solve(job_se_total, job_se_type_total, zz_n_start_time, copy.deepcopy(V_se_j), s_c, a_c,
                                     dis, car_time,
                                     copy.deepcopy(V_j), t2, zz_interval_time, c, rong_liang_zz, zhuan_hua_zz,
                                     box_flow_value, zz_delivery_count, ems_delivery_count, zz_priority,
                                     max_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger)  # 自制时间窗

    solution_x_total, solution_bool_sub_job, solution_bool_C = solve(job_total, ems_n_d_list, job_type_total,
                                                                     ems_n_start_time,
                                                                     sxt, sbsj, sbc_n, job_se_type_total,
                                                                     copy.deepcopy(V_j), s_c, c, p_num,
                                                                     a_c, dis, t1, EMS_interval_time, rong_liang_EMS,
                                                                     zhuan_hua_EMS, box_flow_value, zz_delivery_count,
                                                                     ems_delivery_count, ems_priority,
                                                                     max_time,work_time_list, interval_time,random_ems_index,random_zz_index,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,logger)  # EMS时间窗

    end_solution_x_total = get_end_time(solution_x_total, solution_bool_sub_job, no_work_time_re,
                                        work_time_list)  # 该函数用于得到加入不工作时间后最终的时间窗结果

    end_sxt = get_end_time(sxt, sbsj, no_work_time_re, work_time_list)  # # 该函数用于得到加入不工作时间后最终的时间窗结果

    zz_r = copy.deepcopy(end_sxt)  # 保存自制的真实作业时间

    end_sxt = get_end_zz_time(car_time_before, end_sxt, sbsj)  # 该函数用于将自制的真实工作时间转换为自制的发车表时间

    car = job_total + job_se_total  # 得到最终的装车模型的输出（EMS在前，自制在后）

    goods_num = goods_num_ems + zz_goods_num_new  # 得到最终的货物内部数量的输出

    solution_bool_C = solution_c_ems_process(end_solution_x_total, job_total, job_type_total, solution_bool_sub_job,
                                             solution_bool_C, job_re_ems, copy.deepcopy(V_j), dis, c,
                                             copy.deepcopy(V_se_j))  # 通道资源过多的处理

    sbc = solution_c_zz_process(zz_r, job_se_total, job_se_type_total, sbsj, sbc, zz_job_re, copy.deepcopy(V_se_j),
                                dis, c, copy.deepcopy(V_se_j))  # 通道资源过多的处理

    # # 修正优先级调整后的下标
    # for i in range(len(job_re_ems)):
    #     for j in range(len(job_re_ems[i])):
    #         for k in range(len(job_re_ems[i][j])):
    #             for p in range(len(job_re_ems[i][j][k])):
    #                 job_re_ems[i][j][k][p][0] = index_original_ems[i]
    #
    # # 修正优先级调整后的下标
    # for i in range(len(zz_job_re)):
    #     for j in range(len(zz_job_re[i])):
    #         for k in range(len(zz_job_re[i][j])):
    #             for p in range(len(zz_job_re[i][j][k])):
    #                 zz_job_re[i][j][k][p][0] = index_original_zz[i]


    # 对自制下标的处理，方便EMS和自制下标的合并
    for i in range(len(zz_job_re)):
        for j in range(len(zz_job_re[i])):
            for k in range(len(zz_job_re[i][j])):
                for p in range(len(zz_job_re[i][j][k])):
                    zz_job_re[i][j][k][p][0] += len(job_re_ems)

    # 将自制和EMS的下标合并
    job_re = job_re_ems + zz_job_re

    # 对下标进行最终的处理，得到输出需要的下标
    job_re_end = process_job_re(job_re)



    # 对货物数量和货物内部数量的处理，得到需要的输出
    total_d_num, total_d_goods = d_process(job_re, job_re_end, ems_car_d_num, ems_car_d_type, ems_car_d_goods_num,
                                           zz_car_d_num, zz_car_d_type, zz_car_d_goods_num)



    for i in range(len(job_re_end)):
        for j in range(len(job_re_end[i])):
            for k in range(len(job_re_end[i][j])):
                for p in range(len(job_re_end[i][j][k])):
                    if i < len(job_re_ems):
                        job_re_end[i][j][k][p][0] = index_original_ems[i]
                    else:
                        job_re_end[i][j][k][p][0] = index_original_zz[i - len(job_re_ems)] + len(job_re_ems)

    if bool(no_car_re):
        for i in range(len(no_car_re)):
            f = no_car_re[i][0]
            no_car_re[i][0] = index_original_zz[f] + len(job_re_ems)

    new_no_job_data_re = []
    new_no_car_re = []
    re_s = set()
    for i in range(len(no_car_re)):
        if tuple(no_car_re[i]) not in re_s:
            re_s.add(tuple(no_car_re[i]))
            new_no_car_re.append(copy.deepcopy(no_car_re[i]))
            new_no_job_data_re.append(copy.deepcopy(no_job_data_re[i]))
        else:
            new_no_job_data_re[new_no_car_re.index(no_car_re[i])][0] += copy.deepcopy(no_job_data_re[i][0])
            new_no_job_data_re[new_no_car_re.index(no_car_re[i])][1] += copy.deepcopy(no_job_data_re[i][1])
    end_solution_x_total, end_sxt, zz_r = repair_time(end_solution_x_total, end_sxt, zz_r, min_time)

    return end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re_end, job_total, \
           job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_r, new_no_car_re, new_no_job_data_re


def get_ems_end_time(time_window,ems_end_time):
    '''
    若ems的某个厂家的结束时间为None或0时0分0秒，则将时间窗的最后一个时间间隔的结束时间作为新的结束时间
    :param time_window: 时间窗
    :param ems_end_time: ems结束时间
    :return new_ems_end_time 新的ems结束时间
    '''
    new_ems_end_time = []
    for t in ems_end_time:
        if t == None:
            new_ems_end_time.append(time_window[-1][-1])
        else:

            dt_object = datetime.fromtimestamp(t)
            # 提取小时、分钟和秒
            hour = dt_object.hour
            minute = dt_object.minute
            second = dt_object.second
            if hour==0 and minute ==0 and second==0:
                new_ems_end_time.append(time_window[-1][-1])
            else:
                new_ems_end_time.append(t)

    return new_ems_end_time

def main_fun(ems_goods_num, ems_begin_time, ems_end_time,
            ems_job_type, c, V_j, ems_goods, zz_goods_num,
            zz_begin_time,
            zz_end_time, zz_job_type, zz_goods, s_c,
            V_se_j, fu_dong_EMS, fu_dong_zz,
            rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS,
            zhuan_hua_zz, a_c, p_num, time_window, dis,
            zz_car_num, t1, t2, ems_i_time, zz_i_time, ems_priority, zz_priority, deliver_plan_time, detail_port_num,
            detail_id_arr, insert_time, global_time, box_flow_value, ems_delivery_count, zz_delivery_count, portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger):

    if deliver_plan_time == [] and detail_port_num == [] and detail_id_arr == [] :
        end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re, job_total, \
        job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_real, no_car_re, no_job_data_re = walkthrough_fun(
            ems_goods_num, ems_begin_time, ems_end_time,
            ems_job_type, c, V_j, ems_goods, zz_goods_num,
            zz_begin_time,
            zz_end_time, zz_job_type, zz_goods, s_c,
            V_se_j, fu_dong_EMS, fu_dong_zz,
            rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS,
            zhuan_hua_zz, a_c, p_num, time_window, dis,
            zz_car_num, t1, t2, ems_i_time, zz_i_time, ems_priority, zz_priority, global_time, box_flow_value,
            ems_delivery_count, zz_delivery_count,insert_time, portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger)
    else:
        end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re, job_total, \
        job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_real, no_car_re,no_job_data_re = insert_fun(
            ems_goods_num, ems_begin_time, ems_end_time,
            ems_job_type, c, V_j, ems_goods, zz_goods_num,
            zz_begin_time,
            zz_end_time, zz_job_type, zz_goods, s_c,
            V_se_j, fu_dong_EMS, fu_dong_zz,
            rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS,
            zhuan_hua_zz, a_c, p_num, time_window, dis,
            zz_car_num, t1, t2, ems_i_time, zz_i_time, ems_priority, zz_priority, deliver_plan_time, detail_port_num,
            detail_id_arr, insert_time, global_time, box_flow_value, ems_delivery_count, zz_delivery_count,portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2, ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger)
    return end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re, job_total, \
        job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_real, no_car_re, no_job_data_re

if __name__ == '__main__':
    ems_goods_num =  [[[[1], [1], [1], [1], [1], [1], [3], [1], [1], [2], [2], [1], [1], [2], [1], [1], [3], [1], [1], [2], [1]]], [[[1], [1], [1], [1], [2], [1], [1], [2], [5], [2], [7], [4], [1], [2], [2], [1], [3], [1]]], [[[4], [2], [3], [4], [3], [2], [2], [1], [1], [1], [1], [3], [1], [1], [5, 2], [1, 1], [1], [1], [1], [1, 1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[37], [1], [2], [3], [1], [1, 5], [1, 13], [2], [3], [1], [2], [1], [3], [4], [7], [3], [1], [1], [1, 7], [1], [1], [1], [1], [1]]], [[[1, 2], [1]]], [[[25]]], [[[1]]], [[[2], [1], [1], [1], [1], [1], [1], [2], [1], [1], [1], [1], [2], [1], [3], [1], [1], [1], [1], [1], [1], [1], [1], [2], [1], [1]]], [[[8], [2], [1, 22], [1], [4], [1], [2], [1], [1], [1, 1], [5], [4], [1], [2], [1, 1], [1], [5], [2], [6], [2], [1], [1], [9], [2], [4], [1], [1], [1], [3], [3], [3], [3], [1], [2], [3], [1], [3], [1], [2], [2, 1], [5]]], [[[1], [1]]], [[[2], [1]]], [[[6], [1, 3], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1, 4], [1], [1], [1], [2], [4], [1], [1], [4], [1], [1], [2], [1]]], [[[1], [1], [1]]], [[[1, 21], [1], [2], [1], [1], [2], [1], [1], [1], [1], [1], [2], [2], [1], [1], [1], [2], [3], [1], [1]]], [[[1], [1], [1]]], [[[1], [1], [2], [1], [1], [1]]], [[[1], [4], [2], [1], [3], [1], [1], [1], [1], [1], [1], [2], [1], [1], [3]]], [[[1], [1], [1], [2], [1], [5], [3], [1], [2], [1], [1], [2], [2], [1], [4], [7], [2], [4], [1], [2], [1], [1], [2], [2], [3], [1], [1], [1], [1], [1], [2], [1], [1], [1], [1]]], [[[1], [1], [1, 1], [1], [1], [1], [2], [1], [1], [1], [2]]], [[[1]]], [[[1], [2, 2], [4], [2], [1], [1], [2], [3], [17], [6], [10], [2], [2], [1], [1], [5], [2], [1], [2], [1], [3], [1, 2], [1], [2], [1], [1], [1], [1], [1], [2]]], [[[87], [8], [1], [3], [1], [2], [35], [11], [1, 1], [7], [6], [21]]], [[[1], [1], [2], [1], [1], [1], [3], [1], [1], [1], [2], [1], [1], [1], [1], [1], [1], [1], [2], [1], [1], [3], [1], [1], [5], [2], [1], [1], [2], [1], [1], [1], [1]]], [[[1], [1], [1, 4], [1], [3], [1], [2], [1], [3], [2], [2], [2]]], [[[1], [1, 2], [3, 4], [1, 3], [1], [1], [2], [2], [4], [5], [4]]], [[[5], [4], [3], [2], [1], [1], [3], [2], [3], [1], [2, 2], [1], [1], [1], [2], [1, 1], [1], [2], [1], [1], [2], [2], [2]]], [[[1], [2], [2], [1, 2]]], [[[25], [6], [9], [1], [1], [5]]], [[[8], [4]]], [[[8], [2], [4], [1], [3]]], [[[1], [3]]], [[[7]]], [[[1]]]]
    zz_goods_num = [[[[2], [1], [1], [1]]], [[[1, 1], [1]]], [[[5], [1, 3], [1], [3], [3], [3], [2], [11], [5], [7], [5], [4], [6], [2], [2], [1], [2], [9], [1], [1], [1], [2], [1, 1], [4], [4], [4], [1], [6, 1], [1], [1], [1, 1], [2], [1], [2], [1], [8], [27], [2], [1], [1], [1], [1], [2, 6], [1], [1], [2, 6], [1], [1], [1, 5], [2], [1, 16], [1], [1], [4], [2]]], [[[2], [2], [1], [3], [2], [1], [3], [1], [5], [2], [3], [5], [1, 4]]], [[[1], [1], [1], [1]]], [[[1], [1], [2], [3], [1], [2], [9], [5], [1], [1], [2]]], [[[1], [1], [1], [1]]], [[[2], [2], [1], [1], [3], [2], [3], [2]]], [[[4], [8], [1], [1], [1], [1], [1], [1], [6]]], [[[1], [1], [7], [5], [1], [2], [1]]], [[[7], [1, 3], [2], [1]]], [[[1]]], [[[1], [1], [1], [4], [2], [1]]], [[[1], [1]]], [[[1], [1], [2, 1], [1], [1], [2], [2], [2, 1], [1], [1], [1], [1], [1], [5], [1]]], [[[1], [1], [6], [3], [1], [1], [1], [1, 2], [1], [1], [17], [1], [1], [19], [4], [2], [2], [2], [9], [1], [2], [1, 21], [2], [4], [1], [1], [7], [1]]], [[[1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1]]], [[[4], [1], [1], [1], [1], [1], [2], [1], [1], [1], [1], [1], [1]]], [[[10], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [2]]], [[[2], [1], [1], [1], [1], [1]]], [[[2], [1], [1], [1, 1], [1], [1], [1], [1], [1], [1], [2], [2], [3]]], [[[1], [1]]], [[[1], [2], [3], [14], [1], [1, 4], [2], [3], [9], [1], [1], [2], [1], [1], [3], [2], [1], [1, 1], [1], [2], [4], [5], [6], [2], [6], [2], [1], [2], [1], [1], [2], [3], [1], [5], [2], [5], [1], [3], [3], [1, 1], [2], [1], [5], [8], [4], [1], [6], [1]]], [[[7], [2], [1], [1], [1], [3]]], [[[8], [3, 1]]], [[[1], [1], [1], [1, 2], [12], [2], [21], [3], [2], [1, 6], [1]]], [[[1], [2], [2], [2], [4], [1, 2], [4], [2], [3], [4], [8]]], [[[1], [1], [4], [10], [1, 1], [4], [1], [8], [5], [2], [2], [2], [1], [22], [15], [2]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1, 4], [1], [1], [1]]], [[[1], [1]]], [[[1], [1], [3]]], [[[1]]]]
    ems_job_type = [[[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [0, 1], [1], [1], [1], [0, 1]]], [[[0], [1], [0], [1], [1], [0], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [0, 1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1]]], [[[0, 1], [0]]], [[[1]]], [[[1]]], [[[1], [0], [0], [0], [1], [1], [0], [1], [1], [1], [1], [1], [1], [1], [1], [0], [1], [1], [1], [1], [1], [1], [1], [1], [0], [1]]], [[[1], [1], [0, 1], [1], [1], [1], [0], [0], [1], [0, 1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1]]], [[[1], [1]]], [[[0], [0]]], [[[1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1]]], [[[0, 1], [0], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0]]], [[[1], [1], [1]]], [[[1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1]]], [[[1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [0], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [0, 1], [0, 1], [0, 1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [0], [1], [1], [0, 1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [0, 1]]], [[[1], [1], [1], [0], [1], [1]]], [[[1], [1]]], [[[1], [1], [1], [1], [1]]], [[[1], [1]]], [[[1]]], [[[1]]]]
    zz_job_type = [[[[0], [0], [0], [0]]], [[[0, 1], [1]]], [[[1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0], [0], [1], [1], [1], [1], [1], [0], [1], [0, 1], [1], [1], [1], [1], [0, 1], [1], [1], [0, 1], [1], [1], [1], [1], [0], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [0, 1], [1], [1], [0, 1], [0], [0, 1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1]]], [[[1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1]]], [[[1], [1], [0], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[0], [1], [1], [1], [1], [1], [1]]], [[[1], [0, 1], [1], [0]]], [[[0]]], [[[1], [1], [1], [1], [1], [1]]], [[[1], [0]]], [[[1], [1], [0, 1], [0], [0], [0], [0], [0, 1], [0], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1]]], [[[1], [0], [1], [1], [1], [1]]], [[[1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [0], [0]]], [[[1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1]]], [[[1], [0], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [1]]], [[[1], [0, 1]]], [[[1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [0, 1], [1]]], [[[1], [1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [0, 1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1], [1]]], [[[1], [1], [1], [1], [1], [0], [1], [1], [1], [1], [0], [1], [0, 1], [1], [1], [1]]], [[[1], [1]]], [[[1], [1], [1]]], [[[1]]]]
    fu_dong_EMS = [0.2, 0.2, 0.0, 0.2, 0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.0, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
    rong_liang_EMS = [360, 360, 360, 480, 360, 480, 480, 480, 860, 360, 360, 480, 480, 480, 480, 360, 480, 780, 480, 480, 760, 760, 760, 480, 480, 480, 360, 480, 360, 360, 360, 1000, 480, 480]
    zhuan_hua_EMS =  [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
    fu_dong_zz = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2, 0.2]
    rong_liang_zz = [1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000]
    zhuan_hua_zz = [20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20]
    ems_goods = [[[[250000.0], [1400.0], [144000.0], [20000.0], [640000.0], [9000.0], [20000.0, 2000.0, 104000.0], [162000.0], [81000.0], [10000.0, 579925.0], [1000.0, 1000.0], [80000.0], [15000.0], [14925.0, 409925.0], [3200.0], [3600.0], [10000.0, 300000.0, 390000.0], [162000.0], [15000.0], [79997.0, 70000.0], [435000.0]]], [[[6400.0], [4800.0], [3600.0], [2500.0], [2800.0, 2800.0], [1800.0], [360.0], [400.0, 400.0], [600.0, 600.0, 600.0, 600.0, 600.0], [3000.0, 12000.0], [500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0], [780.0, 780.0, 780.0, 780.0], [4000.0], [1800.0, 1800.0], [3965.0, 9375.0], [4500.0], [20000.0, 50000.0, 200000.0], [4800.0]]], [[[60.0, 60.0, 60.0, 60.0], [1104.0, 5832.0], [1800.0, 860.0, 3600.0], [1544.0, 222.0, 144.0, 1920.0], [2760.0, 1280.0, 2560.0], [129.0, 5540.0], [216000.0, 252000.0], [1000.0], [12973.0], [672.0], [420000.0], [270.0, 270.0, 6390.0], [1920.0], [2000.0], [265.0, 193.0, 114.0, 113.0, 134.0, 15.0, 5.0], [1755.0, 800.0], [700.0], [50000.0], [870000.0], [28200.0, 1200.0]]], [[[1440.0], [120000.0], [2000.0], [24000.0], [3360.0], [40000.0], [6400.0], [30576.0], [2000.0]]], [[[40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0], [600.0], [1200.0, 516.0], [750.0, 750.0, 750.0], [2400.0], [2676.0, 180.0, 180.0, 180.0, 180.0, 139.0], [1440.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0], [1000.0, 14000.0], [750.0, 550.0, 2200.0], [2080.0], [840.0, 840.0], [110000.0], [2500.0, 874.0, 3500.0], [400.0, 400.0, 400.0, 400.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [800.0, 800.0, 800.0], [14000.0], [3600.0], [1792.0, 112.0, 112.0, 112.0, 112.0, 112.0, 112.0, 112.0], [40.0], [10000.0], [4500.0], [1050.0], [3000.0]]], [[[3200.0, 100.0, 76.0], [3200.0]]], [[[60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0, 60.0]]], [[[5990.0]]], [[[2100.0, 21000.0], [19200.0], [3321000.0], [480000.0], [6400.0], [4000.0], [20400.0], [5000.0, 45000.0], [14400.0], [4000.0], [6000.0], [15000.0], [9975.0, 40000.0], [14000.0], [3024.0, 3024.0, 3024.0], [300000.0], [10400.0], [150000.0], [6300.0], [72000.0], [80000.0], [90000.0], [144000.0], [29970.0, 75000.0], [6250.0], [3000.0]]], [[[2000.0, 2000.0, 2000.0, 2000.0, 1500.0, 4000.0, 1000.0, 4000.0], [14900.0, 120000.0], [3780.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0, 126.0], [3150.0], [5500.0, 1630.0, 5500.0, 5500.0], [15000.0], [360.0, 360.0], [462000.0], [15000.0], [4500.0, 600.0], [1170.0, 1170.0, 195.0, 85.0, 1170.0], [1140.0, 1140.0, 285.0, 1140.0], [435000.0], [7975.0, 40000.0], [750.0, 150.0], [3600.0], [600.0, 600.0, 600.0, 600.0, 1386.0], [15000.0, 299900.0], [675.0, 675.0, 675.0, 675.0, 225.0, 675.0], [110000.0, 140000.0], [44925.0], [15000.0], [320.0, 320.0, 320.0, 320.0, 320.0, 320.0, 320.0, 320.0, 320.0], [1500.0, 1500.0], [1800.0, 600.0, 100.0, 1800.0], [560.0], [16500.0], [2250.0], [1152.0, 1152.0, 1152.0], [1960.0, 1960.0, 1800.0], [1008.0, 1008.0, 1008.0], [1350.0, 1350.0, 1125.0], [79925.0], [9000.0, 90000.0], [20000.0, 10000.0, 110000.0], [3000.0], [1568.0, 3000.0, 3000.0], [59925.0], [2352.0, 21168.0], [750.0, 4500.0, 295.0], [600.0, 600.0, 600.0, 600.0, 600.0]]], [[[600000.0], [280000.0]]], [[[46008.0, 55786.0], [102163.0]]], [[[240.0, 240.0, 240.0, 240.0, 240.0, 240.0], [375.0, 375.0, 375.0, 375.0], [540000.0], [360000.0], [570000.0], [20000.0], [500000.0], [490000.0], [3200.0], [40.0], [15000.0], [2480.0, 104.0, 104.0, 104.0, 104.0], [6000.0], [270000.0], [280000.0], [6400.0, 5600.0], [600.0, 198.0, 24.0, 600.0], [280000.0], [28000.0], [2760.0, 1280.0, 320.0, 2560.0], [375000.0], [465000.0], [20000.0, 400000.0], [48000.0]]], [[[20000.0], [550000.0], [12000.0]]], [[[4800.0, 140.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 45.0], [6400.0], [600000.0, 600000.0], [870000.0], [210000.0], [19000.0, 500000.0], [450000.0], [255000.0], [740000.0], [680000.0], [15000.0], [11228.0, 11185.0], [4000.0, 10000.0], [630000.0], [6000.0], [160000.0], [29945.0, 585000.0], [20000.0, 12000.0, 120000.0], [108000.0], [3756000.0]]], [[[15000.0], [39000.0], [66000.0]]], [[[1600.0], [450.0], [1600.0, 1600.0], [2400.0], [3500.0], [7800.0]]], [[[390000.0], [16.0, 16.0, 16.0, 16.0], [108.0, 108.0], [6000.0], [60000.0, 160000.0, 144000.0], [405000.0], [900000.0], [460000.0], [60.0], [210000.0], [400000.0], [350000.0, 100000.0], [4276000.0], [900000.0], [60.0, 60.0, 60.0]]], [[[100000.0], [390000.0], [465000.0], [210000.0, 800000.0], [120000.0], [4800.0, 4800.0, 4800.0, 4800.0, 4800.0], [100000.0, 19925.0, 150000.0], [60000.0], [5000.0, 20000.0], [50000.0], [200000.0], [10000.0, 50000.0], [50000.0, 150000.0], [20000.0], [470000.0, 300000.0, 450000.0, 30000.0], [18000.0, 18000.0, 18000.0, 18000.0, 18000.0, 18000.0, 12000.0], [3000.0, 3000.0], [195.0, 195.0, 195.0, 195.0], [15000.0], [300000.0, 900000.0], [230000.0], [15000.0], [210000.0, 240000.0], [112000.0, 200000.0], [320000.0, 60000.0, 320000.0], [48000.0], [560000.0], [6000.0], [1200000.0], [20000.0], [240000.0, 480000.0], [210000.0], [180000.0], [15000.0], [30000.0]]], [[[720000.0], [900000.0], [6588000.0, 128000.0], [36000.0], [269990.0], [400000.0], [88000.0, 320000.0], [120000.0], [60000.0], [600000.0], [420000.0, 405000.0]]], [[[360.0]]], [[[50000.0], [3840.0, 4716.0, 5120.0, 2560.0], [384.0, 3360.0, 720.0, 336.0], [240000.0, 780000.0], [25000.0], [300000.0], [36000.0, 200000.0], [1280.0, 600.0, 2560.0], [500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0, 500.0], [4000.0, 4000.0, 4000.0, 4000.0, 4000.0, 4000.0], [2760.0, 2760.0, 2760.0, 2760.0, 2760.0, 2760.0, 2760.0, 640.0, 320.0, 2560.0], [29925.0, 140000.0], [874.0, 580.0], [900000.0], [420000.0], [15000.0, 160000.0, 15000.0, 14925.0, 400000.0], [20000.0, 92000.0], [870000.0], [580.0, 580.0], [600000.0], [12000.0, 2000.0, 4000.0], [84000.0, 1000.0, 1000.0], [705000.0], [6000.0, 3000.0], [600000.0], [250000.0], [400000.0], [4800.0], [320000.0], [250000.0, 520000.0]]], [[[78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0, 78.0], [400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 397.0, 360.0], [4000.0], [40.0, 40.0, 40.0], [120.0], [78.0, 78.0], [240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0, 240.0], [40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0, 40.0], [1280.0, 40.0], [400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0], [300.0, 300.0, 300.0, 300.0, 300.0, 300.0], [80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0, 80.0]]], [[[600000.0], [140000.0], [2963.0, 51000.0], [180000.0], [90000.0], [900000.0], [5700.0, 225.0, 8400.0], [9000.0], [69000.0], [7680000.0], [1000.0, 20000.0], [81000.0], [81000.0], [15000.0], [320000.0], [6400.0], [105000.0], [104975.0], [7850.0, 140000.0], [150000.0], [150000.0], [2000.0, 552.0, 72.0], [60000.0], [20000.0], [330.0, 300.0, 270.0, 270.0, 720.0], [72000.0, 180000.0], [153480.0], [10000.0], [3666.0, 15664.0], [9000.0], [54000.0], [1100000.0], [590000.0]]], [[[460000.0], [160000.0], [2391.0, 20967.0, 10549.0, 12165.0, 4025.0], [19990.0], [120000.0, 20000.0, 320000.0], [1140000.0], [540000.0, 260000.0], [480000.0], [120000.0, 220000.0, 820000.0], [40000.0, 120000.0], [100000.0, 600000.0], [100000.0, 600000.0]]], [[[1950.0], [2000.0, 200.0, 200.0], [4200.0, 2250.0, 25483.0, 1800.0, 1350.0, 2250.0, 900.0], [13000.0, 1000.0, 1000.0, 800.0], [39000.0], [5000.0], [5000.0, 5000.0], [20000.0, 4000.0], [8000.0, 8000.0, 4000.0, 4000.0], [250.0, 250.0, 250.0, 250.0, 250.0], [720.0, 720.0, 720.0, 720.0]]], [[[180000.0, 90000.0, 60000.0, 180000.0, 140000.0], [7500.0, 7500.0, 7500.0, 7500.0], [7000.0, 7000.0, 30000.0], [50000.0, 140000.0], [900000.0], [44000.0], [160000.0, 40000.0, 284000.0], [125000.0, 75000.0], [9254.0, 79990.0, 400000.0], [50000.0], [12000.0, 24000.0, 2400.0, 12000.0], [45000.0], [45000.0], [900000.0], [8000.0, 32000.0], [1215000.0, 81000.0], [8000.0], [54000.0, 120000.0], [780000.0], [3200.0], [5000.0, 2000.0], [600000.0, 900000.0], [1600.0, 38400.0]]], [[[2399.0], [1141.0, 3200.0], [3000.0, 3000.0], [300.0, 640.0, 1021.0]]], [[[400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0], [5000.0, 5000.0, 5000.0, 5000.0, 1800.0, 2700.0], [4000.0, 4000.0, 4000.0, 4000.0, 4000.0, 4000.0, 4000.0, 4000.0, 4000.0], [6400.0], [2000.0], [50000.0, 50000.0, 24000.0, 32000.0, 64000.0]]], [[[3998.0, 10000.0, 4000.0, 2000.0, 10000.0, 10000.0, 10000.0, 10000.0], [9998.0, 10000.0, 2000.0, 10000.0]]], [[[600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0], [2560.0, 2560.0], [600.0, 600.0, 600.0, 600.0], [2000.0], [1020.0, 700.0, 1020.0]]], [[[800.0], [600.0, 600.0, 2400.0]]], [[[4000.0, 4000.0, 1652.0, 2400.0, 720.0, 3200.0, 4000.0]]], [[[800000.0]]]]
    ems_begin_time = [1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720, 1725246720]
    ems_end_time = [1725292799.0, 1725292799.0, 1725206400.0, 1725292799.0, 1725206400.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0, 1725292799.0]
    c = [[[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]], [[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1]]]]  # 件箱，栈板
    V_j = [0.041666666666666664, 0.16666666666666666, 0.05555555555555555]
    zz_begin_time = [[1725280200.0, 1725274800.0, 1725278400.0, 1725262200.0, 1725276600.0, 1725285600.0, 1725258600.0, 1725265800.0, 1725267600.0, 1725256800.0, 1725289200.0, 1725255000.0, 1725269400.0, 1725247800.0, 1725287400.0, 1725282000.0, 1725260400.0, 1725264000.0, 1725283800.0, 1725291000.0], [1725256800.0, 1725276600.0, 1725267600.0, 1725265800.0, 1725264000.0, 1725289200.0, 1725274800.0, 1725285600.0, 1725282000.0, 1725247800.0, 1725255000.0, 1725287400.0, 1725291000.0, 1725262200.0, 1725283800.0, 1725260400.0, 1725269400.0, 1725280200.0, 1725278400.0, 1725258600.0], [1725282000.0, 1725283800.0, 1725285600.0, 1725276600.0, 1725289200.0, 1725265800.0, 1725269400.0, 1725255000.0, 1725291000.0, 1725278400.0, 1725267600.0, 1725258600.0, 1725274800.0, 1725256800.0, 1725287400.0, 1725260400.0, 1725247800.0, 1725264000.0, 1725262200.0, 1725280200.0], [1725258600.0, 1725289200.0, 1725285600.0, 1725255000.0, 1725282000.0, 1725283800.0, 1725267600.0, 1725278400.0, 1725291000.0, 1725264000.0, 1725247800.0, 1725265800.0, 1725280200.0, 1725256800.0, 1725276600.0, 1725260400.0, 1725274800.0, 1725269400.0, 1725262200.0, 1725287400.0], [1725258600.0, 1725280200.0, 1725274800.0, 1725269400.0, 1725265800.0, 1725262200.0, 1725256800.0, 1725282000.0, 1725283800.0, 1725291000.0, 1725255000.0, 1725267600.0, 1725289200.0, 1725278400.0, 1725276600.0, 1725247800.0, 1725260400.0, 1725287400.0, 1725285600.0, 1725264000.0], [1725280200.0, 1725265800.0, 1725287400.0, 1725267600.0, 1725283800.0, 1725256800.0, 1725247800.0, 1725282000.0, 1725289200.0, 1725276600.0, 1725278400.0, 1725255000.0, 1725264000.0, 1725258600.0, 1725262200.0, 1725291000.0, 1725285600.0, 1725260400.0, 1725274800.0, 1725269400.0], [1725287400.0, 1725289200.0, 1725260400.0, 1725258600.0, 1725265800.0, 1725282000.0, 1725256800.0, 1725255000.0, 1725285600.0, 1725262200.0, 1725269400.0, 1725264000.0, 1725267600.0, 1725291000.0, 1725274800.0, 1725276600.0, 1725280200.0, 1725278400.0, 1725247800.0, 1725283800.0], [1725274800.0, 1725280200.0, 1725247800.0, 1725264000.0, 1725278400.0, 1725276600.0, 1725283800.0, 1725258600.0, 1725267600.0, 1725262200.0, 1725256800.0, 1725287400.0, 1725291000.0, 1725255000.0, 1725269400.0, 1725285600.0, 1725289200.0, 1725265800.0, 1725260400.0, 1725282000.0], [1725287400.0, 1725289200.0, 1725260400.0, 1725276600.0, 1725256800.0, 1725274800.0, 1725258600.0, 1725247800.0, 1725255000.0, 1725280200.0, 1725291000.0, 1725282000.0, 1725285600.0, 1725264000.0, 1725269400.0, 1725267600.0, 1725265800.0, 1725262200.0, 1725278400.0, 1725283800.0], [1725278400.0, 1725291000.0, 1725264000.0, 1725287400.0, 1725276600.0, 1725255000.0, 1725269400.0, 1725274800.0, 1725265800.0, 1725258600.0, 1725256800.0, 1725280200.0, 1725267600.0, 1725260400.0, 1725262200.0, 1725283800.0, 1725289200.0, 1725247800.0, 1725285600.0, 1725282000.0], [1725262200.0, 1725267600.0, 1725256800.0, 1725276600.0, 1725280200.0, 1725283800.0, 1725247800.0, 1725255000.0, 1725285600.0, 1725289200.0, 1725260400.0, 1725291000.0, 1725269400.0, 1725278400.0, 1725287400.0, 1725258600.0, 1725265800.0, 1725282000.0, 1725264000.0, 1725274800.0], [1725262200.0, 1725258600.0, 1725269400.0, 1725289200.0, 1725287400.0, 1725247800.0, 1725278400.0, 1725276600.0, 1725264000.0, 1725256800.0, 1725260400.0, 1725282000.0, 1725255000.0, 1725267600.0, 1725285600.0, 1725274800.0, 1725283800.0, 1725265800.0, 1725280200.0, 1725291000.0], [1725274800.0, 1725287400.0, 1725276600.0, 1725283800.0, 1725258600.0, 1725278400.0, 1725264000.0, 1725285600.0, 1725267600.0, 1725247800.0, 1725269400.0, 1725280200.0, 1725256800.0, 1725260400.0, 1725262200.0, 1725291000.0, 1725289200.0, 1725255000.0, 1725282000.0, 1725265800.0], [1725255000.0, 1725267600.0, 1725285600.0, 1725287400.0, 1725283800.0, 1725247800.0, 1725291000.0, 1725276600.0, 1725269400.0, 1725264000.0, 1725258600.0, 1725280200.0, 1725262200.0, 1725265800.0, 1725260400.0, 1725278400.0, 1725274800.0, 1725289200.0, 1725256800.0, 1725282000.0], [1725264000.0, 1725267600.0, 1725255000.0, 1725282000.0, 1725269400.0, 1725289200.0, 1725258600.0, 1725291000.0, 1725262200.0, 1725285600.0, 1725283800.0, 1725247800.0, 1725278400.0, 1725260400.0, 1725276600.0, 1725287400.0, 1725265800.0, 1725256800.0, 1725280200.0, 1725274800.0], [1725267600.0, 1725255000.0, 1725260400.0, 1725291000.0, 1725289200.0, 1725282000.0, 1725258600.0, 1725283800.0, 1725285600.0, 1725265800.0, 1725264000.0, 1725262200.0, 1725256800.0, 1725276600.0, 1725287400.0, 1725247800.0, 1725278400.0, 1725274800.0, 1725269400.0, 1725280200.0], [1725264000.0, 1725282000.0, 1725283800.0, 1725256800.0, 1725265800.0, 1725276600.0, 1725291000.0, 1725262200.0, 1725289200.0, 1725285600.0, 1725278400.0, 1725255000.0, 1725274800.0, 1725267600.0, 1725280200.0, 1725287400.0, 1725269400.0, 1725258600.0, 1725247800.0, 1725260400.0], [1725260400.0, 1725256800.0, 1725285600.0, 1725276600.0, 1725291000.0, 1725287400.0, 1725262200.0, 1725264000.0, 1725283800.0, 1725265800.0, 1725282000.0, 1725269400.0, 1725280200.0, 1725247800.0, 1725274800.0, 1725289200.0, 1725267600.0, 1725258600.0, 1725278400.0, 1725255000.0], [1725265800.0, 1725283800.0, 1725260400.0, 1725262200.0, 1725258600.0, 1725280200.0, 1725264000.0, 1725256800.0, 1725287400.0, 1725285600.0, 1725274800.0, 1725255000.0, 1725291000.0, 1725278400.0, 1725282000.0, 1725267600.0, 1725269400.0, 1725247800.0, 1725276600.0, 1725289200.0], [1725255000.0, 1725267600.0, 1725283800.0, 1725260400.0, 1725269400.0, 1725291000.0, 1725258600.0, 1725280200.0, 1725278400.0, 1725256800.0, 1725282000.0, 1725264000.0, 1725285600.0, 1725247800.0, 1725265800.0, 1725262200.0, 1725289200.0, 1725287400.0, 1725274800.0, 1725276600.0], [1725262200.0, 1725289200.0, 1725269400.0, 1725260400.0, 1725247800.0, 1725276600.0, 1725274800.0, 1725283800.0, 1725282000.0, 1725264000.0, 1725256800.0, 1725265800.0, 1725255000.0, 1725267600.0, 1725280200.0, 1725258600.0, 1725291000.0, 1725278400.0, 1725287400.0, 1725285600.0], [1725276600.0, 1725256800.0, 1725280200.0, 1725282000.0, 1725289200.0, 1725247800.0, 1725283800.0, 1725264000.0, 1725278400.0, 1725265800.0, 1725274800.0, 1725285600.0, 1725255000.0, 1725262200.0, 1725287400.0, 1725267600.0, 1725269400.0, 1725258600.0, 1725291000.0, 1725260400.0], [1725255000.0, 1725280200.0, 1725274800.0, 1725269400.0, 1725247800.0, 1725285600.0, 1725258600.0, 1725276600.0, 1725278400.0, 1725287400.0, 1725264000.0, 1725260400.0, 1725283800.0, 1725256800.0, 1725289200.0, 1725262200.0, 1725291000.0, 1725265800.0, 1725267600.0, 1725282000.0], [1725260400.0, 1725247800.0, 1725291000.0, 1725264000.0, 1725276600.0, 1725274800.0, 1725280200.0, 1725256800.0, 1725283800.0, 1725287400.0, 1725267600.0, 1725269400.0, 1725282000.0, 1725265800.0, 1725258600.0, 1725255000.0, 1725278400.0, 1725289200.0, 1725262200.0, 1725285600.0], [1725260400.0, 1725247800.0, 1725269400.0, 1725264000.0, 1725267600.0, 1725262200.0, 1725285600.0, 1725287400.0, 1725282000.0, 1725256800.0, 1725289200.0, 1725265800.0, 1725276600.0, 1725283800.0, 1725255000.0, 1725291000.0, 1725274800.0, 1725278400.0, 1725280200.0, 1725258600.0], [1725256800.0, 1725278400.0, 1725264000.0, 1725255000.0, 1725265800.0, 1725247800.0, 1725283800.0, 1725267600.0, 1725258600.0, 1725291000.0, 1725280200.0, 1725274800.0, 1725276600.0, 1725262200.0, 1725287400.0, 1725289200.0, 1725282000.0, 1725260400.0, 1725285600.0, 1725269400.0], [1725280200.0, 1725247800.0, 1725283800.0, 1725287400.0, 1725278400.0, 1725267600.0, 1725265800.0, 1725255000.0, 1725264000.0, 1725262200.0, 1725289200.0, 1725291000.0, 1725256800.0, 1725269400.0, 1725282000.0, 1725274800.0, 1725258600.0, 1725260400.0, 1725276600.0, 1725285600.0], [1725267600.0, 1725278400.0, 1725258600.0, 1725262200.0, 1725285600.0, 1725255000.0, 1725276600.0, 1725274800.0, 1725247800.0, 1725269400.0, 1725265800.0, 1725256800.0, 1725283800.0, 1725260400.0, 1725287400.0, 1725291000.0, 1725264000.0, 1725282000.0, 1725280200.0, 1725289200.0], [1725291000.0, 1725265800.0, 1725280200.0, 1725274800.0, 1725256800.0, 1725269400.0, 1725276600.0, 1725278400.0, 1725255000.0, 1725285600.0, 1725264000.0, 1725282000.0, 1725283800.0, 1725262200.0, 1725287400.0, 1725267600.0, 1725289200.0, 1725247800.0, 1725258600.0, 1725260400.0], [1725278400.0, 1725291000.0, 1725269400.0, 1725262200.0, 1725265800.0, 1725258600.0, 1725267600.0, 1725255000.0, 1725264000.0, 1725282000.0, 1725289200.0, 1725256800.0, 1725276600.0, 1725260400.0, 1725287400.0, 1725285600.0, 1725247800.0, 1725280200.0, 1725274800.0, 1725283800.0], [1725291000.0, 1725278400.0, 1725280200.0, 1725285600.0, 1725276600.0, 1725289200.0, 1725255000.0, 1725262200.0, 1725260400.0, 1725247800.0, 1725274800.0, 1725258600.0, 1725264000.0, 1725265800.0, 1725269400.0, 1725282000.0, 1725267600.0, 1725283800.0, 1725256800.0, 1725287400.0], [1725287400.0, 1725291000.0, 1725256800.0, 1725289200.0, 1725267600.0, 1725283800.0, 1725265800.0, 1725278400.0, 1725276600.0, 1725274800.0, 1725247800.0, 1725260400.0, 1725280200.0, 1725285600.0, 1725282000.0, 1725258600.0, 1725269400.0, 1725255000.0, 1725264000.0, 1725262200.0], [1725247800.0, 1725280200.0, 1725262200.0, 1725276600.0, 1725260400.0, 1725267600.0, 1725278400.0, 1725283800.0, 1725255000.0, 1725264000.0, 1725269400.0, 1725282000.0, 1725291000.0, 1725256800.0, 1725285600.0, 1725265800.0, 1725289200.0, 1725287400.0, 1725274800.0, 1725258600.0], [1725282000.0, 1725274800.0, 1725269400.0, 1725264000.0, 1725247800.0, 1725256800.0, 1725258600.0, 1725276600.0, 1725278400.0, 1725291000.0, 1725283800.0, 1725265800.0, 1725285600.0, 1725262200.0, 1725280200.0, 1725260400.0, 1725287400.0, 1725267600.0, 1725289200.0, 1725255000.0]]

    zz_end_time = [[1725282000.0, 1725276600.0, 1725280200.0, 1725264000.0, 1725278400.0, 1725287400.0, 1725260400.0, 1725267600.0, 1725269400.0, 1725258600.0, 1725291000.0, 1725256800.0, 1725271200.0, 1725249600.0, 1725289200.0, 1725283800.0, 1725262200.0, 1725265800.0, 1725285600.0, 1725292799.0], [1725258600.0, 1725278400.0, 1725269400.0, 1725267600.0, 1725265800.0, 1725291000.0, 1725276600.0, 1725287400.0, 1725283800.0, 1725249600.0, 1725256800.0, 1725289200.0, 1725292799.0, 1725264000.0, 1725285600.0, 1725262200.0, 1725271200.0, 1725282000.0, 1725280200.0, 1725260400.0], [1725283800.0, 1725285600.0, 1725287400.0, 1725278400.0, 1725291000.0, 1725267600.0, 1725271200.0, 1725256800.0, 1725292799.0, 1725280200.0, 1725269400.0, 1725260400.0, 1725276600.0, 1725258600.0, 1725289200.0, 1725262200.0, 1725249600.0, 1725265800.0, 1725264000.0, 1725282000.0], [1725260400.0, 1725291000.0, 1725287400.0, 1725256800.0, 1725283800.0, 1725285600.0, 1725269400.0, 1725280200.0, 1725292799.0, 1725265800.0, 1725249600.0, 1725267600.0, 1725282000.0, 1725258600.0, 1725278400.0, 1725262200.0, 1725276600.0, 1725271200.0, 1725264000.0, 1725289200.0], [1725260400.0, 1725282000.0, 1725276600.0, 1725271200.0, 1725267600.0, 1725264000.0, 1725258600.0, 1725283800.0, 1725285600.0, 1725292799.0, 1725256800.0, 1725269400.0, 1725291000.0, 1725280200.0, 1725278400.0, 1725249600.0, 1725262200.0, 1725289200.0, 1725287400.0, 1725265800.0], [1725282000.0, 1725267600.0, 1725289200.0, 1725269400.0, 1725285600.0, 1725258600.0, 1725249600.0, 1725283800.0, 1725291000.0, 1725278400.0, 1725280200.0, 1725256800.0, 1725265800.0, 1725260400.0, 1725264000.0, 1725292799.0, 1725287400.0, 1725262200.0, 1725276600.0, 1725271200.0], [1725289200.0, 1725291000.0, 1725262200.0, 1725260400.0, 1725267600.0, 1725283800.0, 1725258600.0, 1725256800.0, 1725287400.0, 1725264000.0, 1725271200.0, 1725265800.0, 1725269400.0, 1725292799.0, 1725276600.0, 1725278400.0, 1725282000.0, 1725280200.0, 1725249600.0, 1725285600.0], [1725276600.0, 1725282000.0, 1725249600.0, 1725265800.0, 1725280200.0, 1725278400.0, 1725285600.0, 1725260400.0, 1725269400.0, 1725264000.0, 1725258600.0, 1725289200.0, 1725292799.0, 1725256800.0, 1725271200.0, 1725287400.0, 1725291000.0, 1725267600.0, 1725262200.0, 1725283800.0], [1725289200.0, 1725291000.0, 1725262200.0, 1725278400.0, 1725258600.0, 1725276600.0, 1725260400.0, 1725249600.0, 1725256800.0, 1725282000.0, 1725292799.0, 1725283800.0, 1725287400.0, 1725265800.0, 1725271200.0, 1725269400.0, 1725267600.0, 1725264000.0, 1725280200.0, 1725285600.0], [1725280200.0, 1725292799.0, 1725265800.0, 1725289200.0, 1725278400.0, 1725256800.0, 1725271200.0, 1725276600.0, 1725267600.0, 1725260400.0, 1725258600.0, 1725282000.0, 1725269400.0, 1725262200.0, 1725264000.0, 1725285600.0, 1725291000.0, 1725249600.0, 1725287400.0, 1725283800.0], [1725264000.0, 1725269400.0, 1725258600.0, 1725278400.0, 1725282000.0, 1725285600.0, 1725249600.0, 1725256800.0, 1725287400.0, 1725291000.0, 1725262200.0, 1725292799.0, 1725271200.0, 1725280200.0, 1725289200.0, 1725260400.0, 1725267600.0, 1725283800.0, 1725265800.0, 1725276600.0], [1725264000.0, 1725260400.0, 1725271200.0, 1725291000.0, 1725289200.0, 1725249600.0, 1725280200.0, 1725278400.0, 1725265800.0, 1725258600.0, 1725262200.0, 1725283800.0, 1725256800.0, 1725269400.0, 1725287400.0, 1725276600.0, 1725285600.0, 1725267600.0, 1725282000.0, 1725292799.0], [1725276600.0, 1725289200.0, 1725278400.0, 1725285600.0, 1725260400.0, 1725280200.0, 1725265800.0, 1725287400.0, 1725269400.0, 1725249600.0, 1725271200.0, 1725282000.0, 1725258600.0, 1725262200.0, 1725264000.0, 1725292799.0, 1725291000.0, 1725256800.0, 1725283800.0, 1725267600.0], [1725256800.0, 1725269400.0, 1725287400.0, 1725289200.0, 1725285600.0, 1725249600.0, 1725292799.0, 1725278400.0, 1725271200.0, 1725265800.0, 1725260400.0, 1725282000.0, 1725264000.0, 1725267600.0, 1725262200.0, 1725280200.0, 1725276600.0, 1725291000.0, 1725258600.0, 1725283800.0], [1725265800.0, 1725269400.0, 1725256800.0, 1725283800.0, 1725271200.0, 1725291000.0, 1725260400.0, 1725292799.0, 1725264000.0, 1725287400.0, 1725285600.0, 1725249600.0, 1725280200.0, 1725262200.0, 1725278400.0, 1725289200.0, 1725267600.0, 1725258600.0, 1725282000.0, 1725276600.0], [1725269400.0, 1725256800.0, 1725262200.0, 1725292799.0, 1725291000.0, 1725283800.0, 1725260400.0, 1725285600.0, 1725287400.0, 1725267600.0, 1725265800.0, 1725264000.0, 1725258600.0, 1725278400.0, 1725289200.0, 1725249600.0, 1725280200.0, 1725276600.0, 1725271200.0, 1725282000.0], [1725265800.0, 1725283800.0, 1725285600.0, 1725258600.0, 1725267600.0, 1725278400.0, 1725292799.0, 1725264000.0, 1725291000.0, 1725287400.0, 1725280200.0, 1725256800.0, 1725276600.0, 1725269400.0, 1725282000.0, 1725289200.0, 1725271200.0, 1725260400.0, 1725249600.0, 1725262200.0], [1725262200.0, 1725258600.0, 1725287400.0, 1725278400.0, 1725292799.0, 1725289200.0, 1725264000.0, 1725265800.0, 1725285600.0, 1725267600.0, 1725283800.0, 1725271200.0, 1725282000.0, 1725249600.0, 1725276600.0, 1725291000.0, 1725269400.0, 1725260400.0, 1725280200.0, 1725256800.0], [1725267600.0, 1725285600.0, 1725262200.0, 1725264000.0, 1725260400.0, 1725282000.0, 1725265800.0, 1725258600.0, 1725289200.0, 1725287400.0, 1725276600.0, 1725256800.0, 1725292799.0, 1725280200.0, 1725283800.0, 1725269400.0, 1725271200.0, 1725249600.0, 1725278400.0, 1725291000.0], [1725256800.0, 1725269400.0, 1725285600.0, 1725262200.0, 1725271200.0, 1725292799.0, 1725260400.0, 1725282000.0, 1725280200.0, 1725258600.0, 1725283800.0, 1725265800.0, 1725287400.0, 1725249600.0, 1725267600.0, 1725264000.0, 1725291000.0, 1725289200.0, 1725276600.0, 1725278400.0], [1725264000.0, 1725291000.0, 1725271200.0, 1725262200.0, 1725249600.0, 1725278400.0, 1725276600.0, 1725285600.0, 1725283800.0, 1725265800.0, 1725258600.0, 1725267600.0, 1725256800.0, 1725269400.0, 1725282000.0, 1725260400.0, 1725292799.0, 1725280200.0, 1725289200.0, 1725287400.0], [1725278400.0, 1725258600.0, 1725282000.0, 1725283800.0, 1725291000.0, 1725249600.0, 1725285600.0, 1725265800.0, 1725280200.0, 1725267600.0, 1725276600.0, 1725287400.0, 1725256800.0, 1725264000.0, 1725289200.0, 1725269400.0, 1725271200.0, 1725260400.0, 1725292799.0, 1725262200.0], [1725256800.0, 1725282000.0, 1725276600.0, 1725271200.0, 1725249600.0, 1725287400.0, 1725260400.0, 1725278400.0, 1725280200.0, 1725289200.0, 1725265800.0, 1725262200.0, 1725285600.0, 1725258600.0, 1725291000.0, 1725264000.0, 1725292799.0, 1725267600.0, 1725269400.0, 1725283800.0], [1725262200.0, 1725249600.0, 1725292799.0, 1725265800.0, 1725278400.0, 1725276600.0, 1725282000.0, 1725258600.0, 1725285600.0, 1725289200.0, 1725269400.0, 1725271200.0, 1725283800.0, 1725267600.0, 1725260400.0, 1725256800.0, 1725280200.0, 1725291000.0, 1725264000.0, 1725287400.0], [1725262200.0, 1725249600.0, 1725271200.0, 1725265800.0, 1725269400.0, 1725264000.0, 1725287400.0, 1725289200.0, 1725283800.0, 1725258600.0, 1725291000.0, 1725267600.0, 1725278400.0, 1725285600.0, 1725256800.0, 1725292799.0, 1725276600.0, 1725280200.0, 1725282000.0, 1725260400.0], [1725258600.0, 1725280200.0, 1725265800.0, 1725256800.0, 1725267600.0, 1725249600.0, 1725285600.0, 1725269400.0, 1725260400.0, 1725292799.0, 1725282000.0, 1725276600.0, 1725278400.0, 1725264000.0, 1725289200.0, 1725291000.0, 1725283800.0, 1725262200.0, 1725287400.0, 1725271200.0], [1725282000.0, 1725249600.0, 1725285600.0, 1725289200.0, 1725280200.0, 1725269400.0, 1725267600.0, 1725256800.0, 1725265800.0, 1725264000.0, 1725291000.0, 1725292799.0, 1725258600.0, 1725271200.0, 1725283800.0, 1725276600.0, 1725260400.0, 1725262200.0, 1725278400.0, 1725287400.0], [1725269400.0, 1725280200.0, 1725260400.0, 1725264000.0, 1725287400.0, 1725256800.0, 1725278400.0, 1725276600.0, 1725249600.0, 1725271200.0, 1725267600.0, 1725258600.0, 1725285600.0, 1725262200.0, 1725289200.0, 1725292799.0, 1725265800.0, 1725283800.0, 1725282000.0, 1725291000.0], [1725292799.0, 1725267600.0, 1725282000.0, 1725276600.0, 1725258600.0, 1725271200.0, 1725278400.0, 1725280200.0, 1725256800.0, 1725287400.0, 1725265800.0, 1725283800.0, 1725285600.0, 1725264000.0, 1725289200.0, 1725269400.0, 1725291000.0, 1725249600.0, 1725260400.0, 1725262200.0], [1725280200.0, 1725292799.0, 1725271200.0, 1725264000.0, 1725267600.0, 1725260400.0, 1725269400.0, 1725256800.0, 1725265800.0, 1725283800.0, 1725291000.0, 1725258600.0, 1725278400.0, 1725262200.0, 1725289200.0, 1725287400.0, 1725249600.0, 1725282000.0, 1725276600.0, 1725285600.0], [1725292799.0, 1725280200.0, 1725282000.0, 1725287400.0, 1725278400.0, 1725291000.0, 1725256800.0, 1725264000.0, 1725262200.0, 1725249600.0, 1725276600.0, 1725260400.0, 1725265800.0, 1725267600.0, 1725271200.0, 1725283800.0, 1725269400.0, 1725285600.0, 1725258600.0, 1725289200.0], [1725289200.0, 1725292799.0, 1725258600.0, 1725291000.0, 1725269400.0, 1725285600.0, 1725267600.0, 1725280200.0, 1725278400.0, 1725276600.0, 1725249600.0, 1725262200.0, 1725282000.0, 1725287400.0, 1725283800.0, 1725260400.0, 1725271200.0, 1725256800.0, 1725265800.0, 1725264000.0], [1725249600.0, 1725282000.0, 1725264000.0, 1725278400.0, 1725262200.0, 1725269400.0, 1725280200.0, 1725285600.0, 1725256800.0, 1725265800.0, 1725271200.0, 1725283800.0, 1725292799.0, 1725258600.0, 1725287400.0, 1725267600.0, 1725291000.0, 1725289200.0, 1725276600.0, 1725260400.0], [1725283800.0, 1725276600.0, 1725271200.0, 1725265800.0, 1725249600.0, 1725258600.0, 1725260400.0, 1725278400.0, 1725280200.0, 1725292799.0, 1725285600.0, 1725267600.0, 1725287400.0, 1725264000.0, 1725282000.0, 1725262200.0, 1725289200.0, 1725269400.0, 1725291000.0, 1725256800.0]]
    zz_goods = [[[[1440.0, 1440.0], [360.0], [1440.0], [4000.0]]], [[[3200.0, 850.0], [250000.0]]], [[[200.0, 200.0, 200.0, 200.0, 200.0], [12630.0, 900.0, 187.0, 335.0], [2785.0], [3000.0, 3000.0, 3000.0], [7000.0, 500.0, 20000.0], [2750.0, 2750.0, 2750.0], [120.0, 120.0], [75.0, 75.0, 75.0, 75.0, 75.0, 75.0, 75.0, 75.0, 75.0, 75.0, 75.0], [800.0, 800.0, 800.0, 800.0, 400.0], [120.0, 120.0, 120.0, 120.0, 120.0, 120.0, 120.0], [1200.0, 1200.0, 600.0, 189.0, 1200.0], [810.0, 810.0, 810.0, 810.0], [220.0, 220.0, 220.0, 220.0, 220.0, 220.0], [150.0, 1800.0], [1050.0, 300.0], [3600.0], [800.0, 800.0], [800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0], [2000.0], [800.0], [28800.0], [800.0, 800.0], [1200.0, 120.0], [4000.0, 4000.0, 4000.0, 4000.0], [600.0, 600.0, 600.0, 600.0], [188.0, 200.0, 200.0, 200.0], [800.0], [300.0, 900.0, 750.0, 76.0, 1200.0, 2400.0, 93.0], [24367.0], [2000.0], [720.0, 120.0], [4200.0, 4200.0], [4800.0], [3000.0, 4000.0], [800.0], [1440.0, 1440.0, 1440.0, 1440.0, 1440.0, 1440.0, 1440.0, 1440.0], [600.0, 600.0, 600.0, 450.0, 250.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0, 450.0], [5000.0, 8000.0], [4800.0], [200.0], [3776.0], [4800.0], [6400.0, 6400.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0], [4200.0], [3000.0], [3200.0, 3200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0], [150.0], [400.0], [4500.0, 1000.0, 900.0, 900.0, 720.0, 900.0], [1800.0, 2400.0], [400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0], [2800.0], [2800.0], [300.0, 300.0, 30.0, 1200.0], [260.0, 260.0]]], [[[1500.0, 1404.0], [30000.0, 12000.0], [280000.0], [320000.0, 100000.0, 140000.0], [36000.0, 180000.0], [70000.0], [400000.0, 220000.0, 380000.0], [70000.0], [1920.0, 1920.0, 1920.0, 1920.0, 1920.0], [840000.0, 1200000.0], [12000.0, 5960.0, 60000.0], [81000.0, 81000.0, 81000.0, 81000.0, 81000.0], [3000.0, 5963.0, 6000.0, 3000.0, 24000.0]]], [[[102480.0], [72000.0], [30000.0], [144000.0]]], [[[49500.0], [81000.0], [7440.0, 180000.0], [63000.0, 36000.0, 79220.0], [50000.0], [6000.0, 12000.0], [4960.0, 20000.0, 7072.0, 18284.0, 13147.0, 8000.0, 8000.0, 4000.0, 1334.0], [1200000.0, 1200000.0, 200000.0, 220000.0, 1040000.0], [15000.0], [30000.0], [15000.0, 20966.0]]], [[[8000.0], [250000.0], [250000.0], [10000.0]]], [[[16000.0, 21000.0], [8000.0, 32000.0], [186000.0], [15000.0], [1600.0, 1600.0, 924.0], [340000.0, 459925.0], [12000.0, 6000.0, 9000.0], [9600.0, 432.0]]], [[[1600.0, 601.0, 238.0, 1600.0], [1200.0, 300.0, 1200.0, 1600.0, 67.0, 316.0, 21.0, 1600.0], [7000.0], [200000.0], [10000.0], [9994.0], [20000.0], [9600.0], [26.0, 1951.0, 214.0, 1343.0, 49.0, 2267.0]]], [[[5084000.0], [100000.0], [1600.0, 1600.0, 1600.0, 348.0, 796.0, 40.0, 1600.0], [5760.0, 432.0, 432.0, 432.0, 432.0], [14000.0], [54000.0, 81000.0], [81000.0]]], [[[1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0], [48000.0, 1000.0, 15000.0, 8000.0], [524.0, 1600.0], [8950000.0]]], [[[32000.0]]], [[[21000.0], [16620.0], [250000.0], [400.0, 400.0, 400.0, 400.0], [300.0, 2100.0], [170000.0]]], [[[300000.0], [300000.0]]], [[[2400.0], [800.0], [3200.0, 5800.0, 168.0], [1800.0], [3200.0], [720.0, 1350.0], [400.0, 3200.0], [1200.0, 1200.0, 20.0], [24000.0], [50000.0], [3625.0], [1000.0], [5000.0], [200.0, 200.0, 200.0, 200.0, 200.0], [41740.0]]], [[[2800.0], [3597.0], [200.0, 200.0, 200.0, 200.0, 200.0, 200.0], [1300.0, 500.0, 3000.0], [480.0], [4800.0], [3597.0], [6646.0, 3000.0, 3000.0], [3500.0], [3500.0], [200.0, 600.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0, 800.0], [480.0], [2800.0], [200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0, 200.0], [2800.0, 2800.0, 2800.0, 2800.0], [3600.0, 3600.0], [3600.0, 3600.0], [2800.0, 2800.0], [90.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 50.0, 3520.0], [4800.0], [3600.0, 3600.0], [11520.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0, 480.0], [400.0, 4500.0], [4500.0, 4500.0, 4500.0, 4500.0], [3000.0], [4800.0], [253.0, 501.0, 1200.0, 166.0, 47.0, 274.0, 2400.0], [3597.0]]], [[[20000.0], [6300000.0], [300000.0], [10000.0], [250000.0], [10000.0]]], [[[120000.0], [140000.0], [500.0], [1400.0]]], [[[2500.0, 2500.0, 2100.0, 2500.0], [5000.0], [250000.0], [3584.0], [440000.0], [2800.0], [6000.0, 20000.0], [250000.0], [250000.0], [20000.0], [2800.0], [3454.0], [6000.0]]], [[[400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0, 400.0], [250000.0], [250000.0], [20000.0], [28800.0], [90000.0]]], [[[250000.0], [250000.0], [3600.0], [36000.0], [1000.0, 2090.0]]], [[[120000.0, 250000.0], [250000.0], [48300.0], [250000.0], [80000.0], [74000.0]]], [[[10000.0, 30000.0], [9000.0], [4500.0], [16100.0, 2500.0], [10000.0], [2500.0], [20000.0], [3600.0], [20000.0], [3558.0], [10000.0, 20000.0], [9000.0, 6000.0], [3600.0, 3600.0, 3600.0]]], [[[330.0], [1500.0]]], [[[15000.0], [5.0, 670.0], [8400.0, 9600.0, 9600.0], [100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0, 100.0], [2100.0], [58122.0, 1920.0, 1920.0, 1920.0, 1920.0], [5500.0, 5500.0], [147.0, 96.0, 21.0], [200.0, 7200.0, 7200.0, 7200.0, 7200.0, 7200.0, 7200.0, 7200.0, 7200.0], [60000.0], [780000.0], [80000.0, 280000.0], [60000.0], [10000.0], [1200.0, 1200.0, 1200.0], [81000.0, 162000.0], [30000.0], [300.0, 1500.0], [81000.0], [1320.0, 1320.0], [50000.0, 10000.0, 115000.0, 200000.0], [30000.0, 29945.0, 15000.0, 30000.0, 45000.0], [1920.0, 1920.0, 1920.0, 1920.0, 1920.0, 1920.0], [11600.0, 11400.0], [640.0, 640.0, 640.0, 480.0, 200.0, 477.0], [5000.0, 40000.0], [72000.0], [48000.0, 80000.0], [314925.0], [1680.0], [56.0, 148.0], [6300.0, 4000.0, 6300.0], [1800.0], [1320.0, 1320.0, 1320.0, 1320.0, 1320.0], [5760.0, 5760.0], [960.0, 804.0, 54.0, 54.0, 960.0], [5000.0], [30000.0, 30000.0, 15000.0], [960.0, 515.0, 960.0], [46176.0, 4800.0], [2240.0, 2240.0], [45000.0], [960.0, 960.0, 960.0, 440.0, 960.0], [750.0, 250.0, 750.0, 750.0, 750.0, 750.0, 750.0, 500.0], [4800.0, 4800.0, 4800.0, 4800.0], [99000.0], [3200.0, 3200.0, 968.0, 1240.0, 280.0, 3200.0], [60000.0]]], [[[280.0, 280.0, 280.0, 70.0, 32.0, 38.0, 280.0], [30000.0, 30000.0], [18000.0], [12000.0], [3000.0], [800.0, 800.0, 800.0]]], [[[600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 600.0, 1386.0], [720.0, 720.0, 540.0, 60.0]]], [[[144000.0], [4900.0], [72000.0], [2336000.0, 320000.0, 320000.0], [2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 912.0, 78.0, 72.0, 36.0, 680.0], [7000.0, 7000.0], [204.0, 36.0, 1000.0, 72.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 2000.0, 96.0, 80.0, 80.0, 72.0, 84.0, 72.0, 1392.0], [18000.0, 3000.0, 3000.0], [729.0, 11084.0], [2511000.0, 162000.0, 162000.0, 162000.0, 54000.0, 36000.0, 36000.0], [290000.0]]], [[[4500.0], [1100000.0, 1160000.0], [4800.0, 1800.0], [320.0, 240.0], [1330.0, 7980.0, 7980.0, 7980.0], [972000.0, 162000.0, 81000.0], [4500.0, 4500.0, 4500.0, 4500.0], [144000.0, 144000.0], [224000.0, 148000.0, 280000.0], [3840.0, 1344.0, 54.0, 7680.0], [1440.0, 1436.0, 1440.0, 1440.0, 1440.0, 1440.0, 1000.0, 1000.0]]], [[[144000.0], [7980.0], [4500.0, 4500.0, 4500.0, 4500.0], [368.0, 2000.0, 200.0, 112.0, 104.0, 104.0, 2000.0, 2000.0, 800.0, 800.0], [3402000.0, 81000.0], [30000.0, 6000.0, 2980.0, 30000.0], [30000.0], [1440.0, 1440.0, 1440.0, 1440.0, 1440.0, 1440.0, 1000.0, 1000.0], [400000.0, 160000.0, 340000.0, 60000.0, 550000.0], [10948.0, 11183.0], [5314.0, 8840.0], [1600.0, 1600.0], [10029.0], [1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0, 1600.0], [36.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1000.0, 1440.0, 1440.0, 36.0, 36.0, 36.0, 36.0, 36.0, 1000.0], [46000.0, 72000.0]]], [[[1592.0], [10800.0], [2000.0], [12000.0], [25200.0], [480000.0], [10800.0], [16200.0], [2336.0], [2400.0], [9940.0], [3600.0], [2000.0, 400.0, 80.0, 40.0, 1600.0], [2000.0], [81000.0], [24000.0]]], [[[880000.0], [27000.0]]], [[[20000.0], [21000.0], [8000.0, 3000.0, 21000.0]]], [[[6000.0]]]]
    s_c =  [[[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[0, 1], [1, 1, 1, 1, 1]]], [[[1, 0, 1, 0], [1, 1, 1, 1, 1]]]]  # [0,1]表示1楼，[1,0]表示-1楼 件箱，栈板
    V_se_j = [0.041666666666666664, 0.05555555555555555, 0.16666666666666666]
    a_c = 5
    p_num = 6
    time_window = [[1725246720.0, 1725249600.0], [1725255000.0, 1725258600.0], [1725258600.0, 1725262200.0], [1725262200.0, 1725265800.0], [1725265800.0, 1725269400.0], [1725269400.0, 1725271200.0], [1725274800.0, 1725278400.0], [1725278400.0, 1725282000.0], [1725282000.0, 1725285600.0], [1725285600.0, 1725289200.0], [1725289200.0, 1725292799.0]]
    dis = 1
    zz_car_num = [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]]
    zz_i_time =  [600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600, 600]
    ems_i_time = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 600, 0, 0]
    zz_priority = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    ems_priority = [2, 2, 2, 3, 2, 3, 4, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 3, 2, 3, 3, 3, 3, 3, 3, 1, 4, 3]
    deliver_plan_time = []
    detail_port_num = []
    detail_id_arr = []
    # deliver_plan_time = [[[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246750.0, 1725246768.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246738.0, 1725246774.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725247920.0, 1725248112.0], [1725247920.0, 1725247968.0]], [[1725247020.0, 1725247290.0], [1725247020.0, 1725247044.0]], [[1725248250.0, 1725248310.0]], [[1725247872.0, 1725248034.0], [1725247872.0, 1725247896.0]], [[1725246738.0, 1725246774.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246726.0, 1725246738.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725248622.0, 1725248694.0], [1725248622.0, 1725248670.0]], [[1725246750.0, 1725246768.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246931.0, 1725247195.0], [1725246931.0, 1725246956.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246931.0, 1725247195.0], [1725246931.0, 1725246956.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725248694.0, 1725248772.0], [1725248694.0, 1725248742.0]], [[1725248772.0, 1725249216.0], [1725248772.0, 1725248820.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246738.0, 1725246774.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246906.0, 1725247380.0], [1725246906.0, 1725246931.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246738.0, 1725246774.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246726.0, 1725246738.0]], [[1725246750.0, 1725246768.0]], [[1725246726.0, 1725246738.0]], [[1725248694.0, 1725248772.0], [1725248694.0, 1725248742.0]], [[1725246846.0, 1725247086.0], [1725246846.0, 1725246871.0]], [[1725246732.0, 1725246750.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246822.0, 1725246930.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246732.0, 1725246750.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246931.0, 1725247195.0], [1725246931.0, 1725246956.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246931.0, 1725247195.0], [1725246931.0, 1725246956.0]], [[1725248622.0, 1725248694.0], [1725248622.0, 1725248670.0]], [[1725246738.0, 1725246774.0]], [[1725247800.0, 1725247806.0], [1725247800.0, 1725247824.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725247920.0, 1725248112.0], [1725247920.0, 1725247968.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246996.0, 1725247416.0], [1725246996.0, 1725247021.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725248034.0, 1725248112.0], [1725248034.0, 1725248058.0]], [[1725247896.0, 1725248166.0], [1725247896.0, 1725247920.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246906.0, 1725247380.0], [1725246906.0, 1725246931.0]], [[1725248820.0, 1725249450.0], [1725248820.0, 1725248844.0]], [[1725247824.0, 1725247836.0], [1725247824.0, 1725247848.0]], [[1725246738.0, 1725246750.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246846.0, 1725247032.0], [1725246846.0, 1725246870.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246726.0, 1725246738.0]], [[1725246931.0, 1725247195.0], [1725246931.0, 1725246956.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725248814.0, 1725249264.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246738.0, 1725246750.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246768.0, 1725246906.0], [1725246768.0, 1725246792.0]], [[1725246906.0, 1725247380.0], [1725246906.0, 1725246931.0]], [[1725246744.0, 1725246822.0], [1725246744.0, 1725246768.0]], [[1725246750.0, 1725246846.0], [1725246750.0, 1725246774.0]], [[1725248514.0, 1725248622.0], [1725248514.0, 1725248538.0]], [[1725246846.0, 1725247086.0], [1725246846.0, 1725246871.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246732.0, 1725246750.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725248112.0, 1725248142.0], [1725248112.0, 1725248136.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246996.0, 1725247416.0], [1725246996.0, 1725247021.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246732.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725248112.0, 1725248142.0], [1725248112.0, 1725248136.0]], [[1725246720.0, 1725246732.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246732.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246726.0]], [[1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246744.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246804.0, 1725247020.0], [1725246804.0, 1725246838.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246726.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725248136.0, 1725248652.0], [1725248136.0, 1725248328.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246888.0], [1725246720.0, 1725246744.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]], [[1725246720.0, 1725246804.0], [1725246720.0, 1725246745.0]]]  # 对应订单详情的时间
    # detail_port_num = [[0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1], [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0], [1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]]  # 订单详情对应的交付对象的下标，0在后为EMS，0在前为自制
    # detail_id_arr = [[0, [2]], [[24], 0], [[15], 0], [[19], 0], [[28], 0], [[24], 0], [[19], 0], [0, [3]], [[23], 0], [0, [12]], [0, [5]], [[28], 0], [[24], 0], [[24], 0], [[22], 0], [[24], 0], [0, [10]], [[15], 0], [[0], 0], [[26], 0], [[24], 0], [[26], 0], [[24], 0], [[24], 0], [[17], 0], [0, [19]], [0, [24]], [[24], 0], [[17], 0], [[28], 0], [[17], 0], [[17], 0], [[21], 0], [[19], 0], [[28], 0], [[17], 0], [[22], 0], [[15], 0], [[10], 0], [0, [19]], [[12], 0], [[13], 0], [[17], 0], [[2], 0], [[14], 0], [[17], 0], [[24], 0], [[24], 0], [[19], 0], [[19], 0], [[13], 0], [[17], 0], [[26], 0], [[17], 0], [[26], 0], [0, [10]], [[28], 0], [0, [13]], [[19], 0], [[17], 0], [0, [3]], [[2], 0], [[19], 0], [[9], 0], [0, [2]], [[17], 0], [[19], 0], [[19], 0], [[2], 0], [[17], 0], [0, [9]], [0, [7]], [[24], 0], [0, [2]], [[24], 0], [[19], 0], [[21], 0], [0, [15]], [0, [1]], [[16], 0], [[19], 0], [[4], 0], [[24], 0], [[10], 0], [[26], 0], [[24], 0], [0, [28]], [[2], 0], [[17], 0], [[24], 0], [[24], 0], [[24], 0], [[24], 0], [[16], 0], [[24], 0], [[17], 0], [[24], 0], [[24], 0], [[19], 0], [[17], 0], [[2], 0], [[24], 0], [[17], 0], [[19], 0], [[24], 0], [[21], 0], [[19], 0], [[17], 0], [0, [22]], [[12], 0], [[2], 0], [[13], 0], [0, [2]], [[0], 0], [0, [2]], [0, [16]], [[8], 0], [[8], 0], [[8], 0], [0, [2]], [[0], 0], [[9], 0], [[8], 0], [[31], 0], [[8], 0], [[8], 0], [[5], 0], [[0], 0], [[0], 0], [0, [16]], [[5], 0], [[8], 0], [0, [2]], [[0], 0], [[0], 0], [[5], 0], [[0], 0], [[8], 0], [[8], 0], [[0], 0], [[20], 0], [[31], 0], [[8], 0], [[0], 0], [[31], 0], [0, [2]], [[0], 0], [[0], 0], [[0], 0], [[0], 0], [[8], 0], [[31], 0], [[0], 0], [[0], 0], [[2], 0], [[0], 0], [[8], 0], [[0], 0], [[0], 0], [[0], 0], [[8], 0], [[7], 0], [[0], 0], [[0], 0], [[8], 0], [[0], 0], [0, [2]], [[0], 0], [[0], 0], [[8], 0], [[8], 0]]
    t1 = 30
    t2 = 30
    insert_time = 1725255900.0
    # global_time= [[1715011201.0, 1715040000.0], [1715058000.0, 1715097599.0], [1714838401.0, 1714867200.0], [1714780800.0, 1714795200.0], [1714971600.0, 1715011199.0], [1714798800.0, 1714838399.0], [1715144400.0, 1715183999.0], [1715097601.0, 1715126400.0], [1714885200.0, 1714924799.0], [1715126400.0, 1715140800.0], [1714924801.0, 1714953600.0], [1714953600.0, 1714968000.0], [1715040000.0, 1715054400.0], [1714867200.0, 1714881600.0], [1714752001.0, 1714780800.0]]
    global_time = [[1725274800.0, 1725292799.0], [1725237000.0, 1725249600.0], [1725217200.0, 1725231600.0], [1725255000.0, 1725271200.0]]
    box_flow_value = 27.7775  # 各通道最大流量限制
    ems_delivery_count = 6  # ems件箱最大同时交付数量较
    zz_delivery_count = 2  # 自制件箱最大同时交付数量较
    portEmsLpnNum3 = 200
    portEmsLpnNum2 = 400
    portSelfLpnNum2 = 200
    ems_detail_add_date = [[[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19]], [[1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19]], [[1724900562.189]]]
    zz_detail_add_date =  [[[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19]], [[1724342400.19, 1724342400.19, 1724342400.19]], [[1724342400.19]]]

    is_splitting_car = False

    end_solution_x_total, solution_bool_sub_job, solution_bool_C, end_sxt, sbsj, sbc, car, job_re, job_total, \
    job_type_total, job_se_total, job_se_type_total, goods_num, total_d_num, total_d_goods, zz_real, no_car_re,no_job_data_re = main_fun(
        ems_goods_num, ems_begin_time, ems_end_time,
        ems_job_type, c, V_j, ems_goods, zz_goods_num,
        zz_begin_time,
        zz_end_time, zz_job_type, zz_goods, s_c,
        V_se_j, fu_dong_EMS, fu_dong_zz,
        rong_liang_EMS, rong_liang_zz, zhuan_hua_EMS,
        zhuan_hua_zz, a_c, p_num, time_window, dis,
        zz_car_num, t1, t2, ems_i_time, zz_i_time, ems_priority, zz_priority, deliver_plan_time, detail_port_num,
        detail_id_arr, insert_time, global_time, box_flow_value, ems_delivery_count, zz_delivery_count, portEmsLpnNum3,portEmsLpnNum2,portSelfLpnNum2,ems_detail_add_date,zz_detail_add_date,is_splitting_car,logger=Logger)

    print("end_solution_x_total: ", end_solution_x_total)
    print("solution_bool_sub_job: ", solution_bool_sub_job)
    print("solution_bool_C: ", solution_bool_C)
    print("end_sxt: ", end_sxt)
    print("sbsj: ", sbsj)
    print("sbc: ", sbc)
    print("car: ", car)
    print("job_re: ", job_re)
    print("job_total: ", job_total)
    print("job_type_total: ", job_type_total)
    print("job_se_total: ", job_se_total)
    print("job_se_type_total: ", job_se_type_total)
    print("goods_num: ", goods_num)
    print("total_d_num: ", total_d_num)
    print("total_d_goods: ", total_d_goods)
    print("zz_real: ", zz_real)
    print("no_car_re: ", no_car_re)
    print("no_job_data_re", no_job_data_re)


    time_save = []
    for i in range(len(end_sxt)):
        sub_time_save = []
        for j in range(len(end_sxt[i])):
            sub_sub_time_save = []
            for k in range(len(end_sxt[i][j])):
                sub_sub_sub_time_save = []
                for a in range(len(end_sxt[i][j][k])):
                    sub_sub_sub_sub_time_save = []
                    for u in range(len(end_sxt[i][j][k][a])):
                        timeArray = time.localtime(end_sxt[i][j][k][a][u])
                        otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
                        sub_sub_sub_sub_time_save.append(otherStyleTime)
                    sub_sub_sub_time_save.append(sub_sub_sub_sub_time_save)
                sub_sub_time_save.append(sub_sub_sub_time_save)
            sub_time_save.append(sub_sub_time_save)
        time_save.append(sub_time_save)

    time_save2 = []
    for i in range(len(zz_real)):
        sub_time_save = []
        for j in range(len(zz_real[i])):
            sub_sub_time_save = []
            for k in range(len(zz_real[i][j])):
                sub_sub_sub_time_save = []
                for a in range(len(zz_real[i][j][k])):
                    sub_sub_sub_sub_time_save = []
                    for u in range(len(zz_real[i][j][k][a])):
                        timeArray = time.localtime(zz_real[i][j][k][a][u])
                        otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
                        sub_sub_sub_sub_time_save.append(otherStyleTime)
                    sub_sub_sub_time_save.append(sub_sub_sub_sub_time_save)
                sub_sub_time_save.append(sub_sub_sub_time_save)
            sub_time_save.append(sub_sub_time_save)
        time_save2.append(sub_time_save)

    zz_begin_time_save = []
    for i in range(len(zz_begin_time)):
        sub_time_save = []
        for j in range(len(zz_begin_time[i])):
            sub_sub_time_save = []
            timeArray = time.localtime(zz_begin_time[i][j])
            otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
            sub_time_save.append(otherStyleTime)
        zz_begin_time_save.append(sub_time_save)

    zz_end_time_save = []
    for i in range(len(zz_end_time)):
        sub_time_save = []
        for j in range(len(zz_end_time[i])):
            sub_sub_time_save = []
            timeArray = time.localtime(zz_end_time[i][j])
            otherStyleTime = time.strftime("%Y-%m-%d %H:%M:%S", timeArray)
            sub_time_save.append(otherStyleTime)
        zz_end_time_save.append(sub_time_save)
    print(111)